您的位置:首页 > 编程语言 > C语言/C++

逆向还原C语言代码 练习1

2016-11-30 10:01 232 查看
找了个C语言100列 用来练习OD还原C语言代码 至于C+的 以后也会写今天的课件下载 链接: http://pan.baidu.com/s/1nvApltJ 密码: sgur我们先来看第一个程序,我们先分析Debug的 Debug为了方便调试,代码都是一对一的翻译 没做什么优化,还原起来比较好上手,先用OD载入,我们看到一个GetCommandLineA 我们知道 C语言真正的入口并不是main 而在main之前 会调用GetCommandLineA ,也就是说,我们往下面翻一下 可能会找到main函数,我们往下翻一下这段代码很可疑,可能传递了3个参数,前面的ecx edx也可能是参数,所以我说可能传递了3个, 然后 call下面 add esp,0xc 表示这个函数是外平栈,那么ecx edx应该不是参数,这个call很可能是main 我们进去看看 是个jmp 再跟过去 打个断点看到如下的代码:我鼠标选中的(紫色背景)的代码 是debug版本初始化栈用的,先不管他,看箭头处 这里有个call push进去的参数是”\n” 我们看看这个call是什么,选中这行 按回车键跟过去看这代码 应该是C语言的printf函数没错了,我们加个标签,这样再调用这个函数的时候就能看出来是他了,我们选中这行代码的段首 然后 右键 –标签 或者按快捷键 : 在弹出来的对话框中输入 printf 如下图这样 以后调用printf的地方就会显示出来了,看下面的效果OK ~我们看看Call的下面的代码代码有点多,先不急,我们先简单的浏览下 我们知道 ebp+4是函数返回地址 ebp+8 +c ….是函数的参数,而ebp-4 -8 ……是函数的局部变量,简单的看一下,这一段代码里面 到retn之前有3个ebp- 也就是有3个参数咯~ 我们来简单规定下 ebp-4 我们叫他i
-8 叫j -c叫khttp://www.dbgpro.com/archives/384.html[Asm] 纯文本查看 复制代码?
[size=0.8em]我们先看下这一段,先给i赋值1 然后立马就跳了,跳到和5比较的地方了,然后判断 如果大于5 又跳了,我们看看他跳过去的地方的代码004010B4 |> \33C0 xor eax,eax ; kernel32.BaseThreadInitThunk004010B6 |. 5F pop edi
; kernel32.7578336A004010B7 |. 5E pop esi ; kernel32.7578336A004010B8 |. 5B pop ebx ; kernel32.7578336A004010B9 |. 83C4 4C add
esp,0x4C[size=0.8em]也就是说
大于5 就结束了 如果小于5的话 就执行0040104D |. C745 F8 01000>|mov dword ptr ss:[ebp-0x8],0x100401054 |. EB 09 |jmp short Test1_Dd.0040105F00401056 |> 8B4D F8
|/mov ecx,dword ptr ss:[ebp-0x8] ; kernel32.7578336A00401059 |. 83C1 01 ||add ecx,0x10040105C |. 894D F8 ||mov dword ptr ss:[ebp-0x8],ecx0040105F |> 837D F8 05 | cmp dword ptr ss:[ebp-0x8],0x5 00401063 |. /7D 4D ||jge
short Test1_Dd.004010B2 也就说 如果小于5的话 就执行j=1 然后判断j是不是大于5 如果大于5的话 就跳转 看看跳到哪里去了004010B2 |>^\EB 8A \jmp short Test1_Dd.0040103E调到一个jmp 我们再看看jmp跳过去的地方的代码0040103E |> /8B45 FC /mov eax,dword ptr ss:[ebp-0x4]00401041 |. |83C0 01 |add eax,0x100401044 |. |8945 FC |mov dword ptr
ss:[ebp-0x4],eax ; kernel32.BaseThreadInitThunk00401047 |> |837D FC 05 cmp dword ptr ss:[ebp-0x4],0x50040104B |. |7D 67 |jge short Test1_Dd.004010B4[size=0.8em]是不是有点眼熟,刚才判断i小于5的地方么?而且在判断之前还对i+1了那么我们就能确定了 最起码 j外面有个for循环 代码应该是这样for (i=1;i<5;i++){ j = 1; if(j<5) { }}我们再看看
刚刚判断j大于5的那里 如果小于5会怎么样[Asm] 纯文本查看 复制代码?
[size=0.8em]嗯?如果j<小于5就给K赋值1
然后立马jmp到比较处 判断k是不是小于5 如果不小于就跳过去 老规矩 我们看看 跳过去会怎么样004010B0 |>^\EB A4 |\jmp short Test1_Dd.00401056又是一个jmp 看看跳过去的地址,我们分析分析[Asm] 纯文本查看 复制代码?
[size=0.8em]这明显是比较j小于5的代码
而且是调到j+1的地方那么 我们的更新刚才还原出来的代码了应该是这样for (i=1;i<5;i++){ for (j=1;j<5;j++) { k=1; if(k<5) {} }}好,我们在看看
k如果不跳会怎么样[C++] 纯文本查看 复制代码?
[size=0.8em]好吧~k如果不跳
执行的代码有点小多。。。先不管,我们看到k里面有3个跳转,跳转的目标地址都一样 我们看看跳过去会怎么样004010AE |>^\EB BE ||\jmp short Test1_Dd.0040106E跳过去又是一个jmp 难道k也是循环?我们过去看看0040106E |> /8B55 F4 ||/mov edx,dword ptr ss:[ebp-0xC]00401071 |. |83C2 01 |||add edx,0x100401074 |. |8955 F4 |||mov dword ptr ss:[ebp-0xC],edx ; Test1_Dd.<ModuleEntryPoint>00401077 |> |837D F4 05 || cmp dword ptr ss:[ebp-0xC],0x50040107B |. |7D 33 |||jge short Test1_Dd.004010B0果然,k也是循环 那么 我们目前还原出来的代码应该是这样[C++] 纯文本查看 复制代码?
好了 接着 我们来看看k这个循环里面的代码[Asm] 纯文本查看 复制代码?
[size=0.8em]看到这么多代码
先不要慌,我们先 一句一句来读 ,下面的代码跟上面一样 但是加了注释[Asm] 纯文本查看 复制代码?
通过上面的注释可以得出一个结论,这里是判断如果 i j k互不相等 就输出 也就是说 能还原出如下代码[C++] 纯文本查看 复制代码?
3个if我们可以用 && 优化一下 最终的结果如下[C++] 纯文本查看 复制代码?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: