《汇编语言》学习笔记
寄存器(reg): CPU中存储数据的器件
在8086CPU中,有14个寄存器,可以分为8个通用寄存器、1个指令指针寄存器、1个标志寄存器以及4个段寄存器
通用寄存器:用于传送和暂存数据,也可参与算术逻辑运算,并保存运算结果。AH&AL = AX (accumulator):累加寄存器,主要是在进行运算的时候存放操作数,同时所有的I/O指令都使用这一寄存器与外界设备传送数据BH&BL = BX (basic):基址寄存器,用于地址的索引CH&CL = CX (count):计数寄存器,用于计数,在移位操作以及循环(loop)时作为隐含的计数器DH&DL = DX(data):数据寄存器,用于数据传递。在书中以8086CPU为例,如果是要用32位的数作为被除数时,通过使用DX与AX存放数据,DX放高16位,AX放低16位SP(Stack Pointer):堆栈指针,与SS配合使用,可指向目前的堆栈位置(也就是当前栈顶的偏移地址)BP(Base Pointer):基址指针寄存器,可用作SS的一个相对基址位置SI(Source Index):源变址寄存器,可 ...
逆向工程学习--Acid burn
0x00 前言
这些CreakMe小程序是从吾爱破解上找到的160个练习然后最近在学逆向&汇编就拿来练练手
0x01 注册码的破解最近才开始学用Ollydbg不熟悉。。然后快捷键还有功能什么的还没有把握所以一开始动态调试就是一个断点一个断点的下跟踪程序的运行,要找到主要执行的地方就异常的慢。。看了一下别人做的才学会在运行过程中F12直接暂停程序运行跟踪汇编位置。。程序界面是这么一个样子:就是要输入用户名对应注册码的样子,先随便输入一个,然后等提示框,F12暂停定位到对应的位置Alt-K到堆栈界面,可以看到MessageBox函数的调用有两个对MessageBox的调用,能大致确定是下面一个才是后面弹出提示框的时候调用的函数然后进到这个函数的位置,在调用MessageBox的函数头部打个断点,再重复一次运行到断点位置能看到右下角的栈窗口看到被压栈的有个可疑的字符串。。试一试输入然后提交试试,然后就成功了调用的这个函数应该是为了输出失败信息,然后在这之前应该有一个函数是用于验证注册码的,可以在栈里看到,这里用于下面的分析注册码生成算法
0x02 注册码算法分析从上面调用Messa ...
PE文件结构
前言
PE文件的全称是Portable Executable,意为可移植的可执行的文件,常见的EXE、DLL、OCX、SYS、COM都是PE文件,PE文件是微软Windows操作系统上的程序文件(可能是间接被执行,如DLL)——百度百科
简述PE文件使用的是平面地址空间,代码和数据被合并在一起,组成庞大的组织结构。文件的内容分割为不同的区块(如.data、.idata、.text,这些区块甚至可以自己命名),区段中包含代码数据,各个区块按照页边界来对齐,区块没有限制大小,是一个连续的结构。每块都有他自己在内存中的属性,比如:这个块是否可读可写,或者只读等等。在加载的时候,windows加载器遍历整个PE文件并决定文件的哪个部分被映射,这种映射方式是将文件较高的偏移位置映射到较高的内存地址中。
基地址PE文件加载到内存后,内存中的版本被称为模块。映射文件的起始地址被成为模块句柄,可以通过模块句柄访问内存中的其他数据结构。这个初始的内存地址也被称为基地址(ImageBase)。
VA & RVAVA:进程虚拟内存的绝对地址RVA:相对虚拟地址,从某个基准地址开始的相对地址虚拟地址 ...
Codeforces1207-C Gas Pipeline
题目大意:在$x$轴的非负区域,有长度为$n$的路,需要在这条路上铺设管道;如果在某个位置是十字路口的话,需要将这个位置的管道高度铺设在$y = 2$的位置上面,而在非十字路口的位置,可以铺设在$y = 1$的位置,也可以铺设在$y = 1$的位置,而不同高度的情况下需要对应高度的管道架;设一单位的管道需要的费用是$a$,一单位管道架需要的费用是$b$,求铺设到终点所需的最小费用
被B题卡了快一个小时才看C题。。满足最优子结构和无后效性就是DP了这次又是写出了C的时候没写出B呢。。。设$f_{i,j}$为铺设到$i$位置的时候高度为j的最小花费那么可以得到转移方程在$s_i$为1的时候:$$\begin{cases}f[i][0] = INF\f[i][1] = min(f[i-1][0] + 2a,f[i-1][1] + a) + 2b\\end{cases}$$在$s_i$为0的时候:$$\begin{cases}f[i][0] = min(f[i-1][1] + 2a,f[i-1][0] + a) + b\f[i][1] = min(f[i-1][0] + 2a,f[i-1][1 ...
Codeforces1207-B Square Filling
题目大意:给出两个$n \cdot m$的矩阵$A$和$B$,一开始矩阵$B$全为0,每次可以选定一个坐标$(x,y)(1 \le x < n、1 \le y < m)$,将$(x,y)、(x,y + 1)、(x + 1,y)、(x + 1,y + 1)$都变成1,求将矩阵$B$变为$A$的最小步数,并输出所有的操作的坐标。
这个思维题又把我卡死了,C题都写得出来但是我写不出这个B,结束前3分钟才给A掉然后没时间写别的了。。要操作的次数最少,也就是说每次操作要保证改变的0的数量最多把一个0的位置变成1,假设这个坐标是$(x,y)$,那么可以通过修改$(x - 1,y - 1)、(x - 1,y)、(x,y - 1)、(x,y)$这四个位置来达到那么每次直接扫描一下$B$中是0但$A$中是1的位置,如果操作的区域中在$A$中没有0,就可以求出一个能使得这次操作最大化的操作位置来进行操作显然时间复杂度是$O(nm)$的,然后我这里还带了一些常数,但是影响不大
这一场从$\Delta$-80+在最后3分钟拉回来。。最后涨了一分。。。(我还真是个弟弟。。思维题必杀我
1234567 ...
Codeforces-Round#580(Div.2)解题报告
A - Choose Two Numbers给出两个数组,长度分别为$ n、m(1 \le n \le 100、1 \le m \le 100)$,找出两个分别属于两个数组的数,使得它们的和不在两个数组里
暴力
裸暴力,手滑了两发白给。。
123456789101112131415161718192021int n,m;int a[300],b[300];bool mp[1000];int main() { mst(mp,0); ios::sync_with_stdio(0); cin>>n; for(int i = 1;i <= n;i++) cin>>a[i],mp[a[i]] = 1; cin>>m; for(int i = 1;i <= m;i++) cin>>b[i],mp[b[i]] = 1; for(int i = 1;i <= n;i++) { for(int j = 1;j <= m;j++) { ...
Codeforces-570-div3解题报告
div3都能给我打掉分,我真的是个菜狗了。。
A - Nearest Interesting Number
给出一个数$ n $问大于等于它的哪个数的每个位相加起来和是4的倍数
枚举
123456789101112131415161718int a;int main(){ cin >> a; for(int i = a;i <= 2000;i++){ int tmp = i; int x = 0; while(tmp){ x += tmp % 10; tmp /= 10; } if(x % 4 == 0){ cout<<i<<endl; break; } } return 0;}
B - Equalize Prices
给出一个数列$a_i$,问能不能找到一个尽量大的数 ...
UESTC暑假前集训-字符串与搜索-解题报告
A - qh与复读机I
A、每次按顺序给出$ n $个字符串,求出每个字符串是前面多少个字符串的前缀和后缀
tire树因为题面给定数据范围$\sum |S_i| < 1e6$,也就是说如果建一棵树的话结点数是不会超过这么多的,而且遍历的时候也是,那么考虑正序和逆序建树,每次建树的同时到达最后一个结点返回当前结点已经记录的单词数量,也就分别对应了前缀和后缀时间复杂度$O(n)$
123456789101112131415161718192021222324252627282930313233343536373839404142#define maxn 1000007struct Node{ int child[26]; int sum; void init(){ for(int i = 0;i < 26;i++) child[i] = 0; sum = 0; }}Tree[2][maxn];int cnt1 = 0,cnt2 = 0;int insert(bool statu,const string& s){ ...
UESTC暑假前集训—图论-解题报告
A - 迷宫
给出一个带权有向图,翻转一条边的代价是其权重,求出翻转边后图中无环的最小代价
二分 拓扑判环一开始只能想到要让图中没有环,但是想不清楚怎么操作,于是等到题解emmmm考虑对于要改变的边,相当于删去之后反向加回来,那么代价就是边里面权值最大的二分权值,权值越大的可以改变的边越多,二分最少的代价使得不存在环即可
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253int n,m;int u,v;ll w;int top[maxn],in[maxn];vector<Edge> G1;vector<int> edges[maxn];bool check(ll now){ int cnt = 0; for(int i = 1;i <= n;i++) edges[i].clear(); mst(in,0); mst(top,0); for(int i = 0;i < m;i++){ i ...
UESTC暑假前集训-动态规划-解题报告
A - oy环游世界
A、给定n个点,求出从起点开始遍历到最后一个点的最短曼哈顿距离
状态压缩n最多有17个点,可以考虑将17个点压缩到一个int里面,这个时候可以考虑一个状态$f _ {S,i}$,表示遍历了集合S后以i为终点的路径的最短的距离,状态转移方程为:$$f_{S,j} = min(f_{S,j},f_{S_j,j + dist(j,k)})$$$S_j$表示集合$S$除去点$j$后的集合
12345678910111213141516171819202122232425262728293031323334struct Point{ ll x,y; ll operator - (const Point& a) const{ return abs(x - a.x) + abs(y - a.y); }}all[20];ll n,s;ll f[1<<20][20];int main(){ cin>>n>>s; mst(f,0x3f3f3f); for(ll i = 0;i < ...