今天好不容易在网管中心的一台垃圾机子上装好VC和OD。。
在百度找到一些简单,适合用来反汇编的算法:
http://blog.youkuaiyun.com/yanfan0916/article/details/6450472
程序源码:
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
int i,j,k;
printf("\n");
for(i=1;i<5;i++)
for(j=1;j<5;j++)
for(k=1;k<5;k++)
{
if(i!=k&&i!=j&&j!=k)
printf("%d,%d,%d/n",i,j,k);
}
}
{
int i,j,k;
printf("\n");
for(i=1;i<5;i++)
for(j=1;j<5;j++)
for(k=1;k<5;k++)
{
if(i!=k&&i!=j&&j!=k)
printf("%d,%d,%d/n",i,j,k);
}
}
OD载入,一直F8走,发现竟然没有停住直接结束了程序,原来因为本C程序中未有要求用户输入的函数,所以
我们要自己注意OD中代码调用了哪个call之后屏幕开始输出数据了。
00401140 |. E8 BBFEFFFF call 00401000
走到这里的时候发现已经有东西输出了,于是断下 重新加载程序 运行到此处再F7单步!
OD反汇编代码:
00401000 /$ 53 push ebx
00401001 |. 56 push esi
00401002 |. 57 push edi ; 看来就是把这三个寄存器当做i j k了
00401003 |. 68 3C704000 push 0040703C
00401008 |. E8 53000000 call 00401060 ; 输出空行
0040100D |. 83C4 04 add esp, 4 ; 恢复堆栈(C函数)
00401010 |. BB 01000000 mov ebx, 1 ; i
00401015 |> BF 01000000 /mov edi, 1 ; j
0040101A |> BE 01000000 |/mov esi, 1 ; k
0040101F |> 3BDE ||/cmp ebx, esi ; cmp i,k
00401021 |. 74 18 |||je short 0040103B ; 不符合条件i!=k则跳转,进入本层循环的下一次循环或因循环变量不小于5而退出本层
00401023 |. 3BDF |||cmp ebx, edi
00401025 |. 74 14 |||je short 0040103B ; 不符合条件i!=j则跳转,进入本层循环的下一次循环或因循环变量不小于5而退出本层
00401027 |. 3BFE |||cmp edi, esi
00401029 |. 74 10 |||je short 0040103B ; 不符合条件j!=k则跳转,进入本层循环的下一次循环或因循环变量不小于5而退出本层
0040102B |. 56 |||push esi
0040102C |. 57 |||push edi
0040102D |. 53 |||push ebx
0040102E |. 68 30704000 |||push 00407030 ; ASCII "%d,%d,%d/n"
00401033 |. E8 28000000 |||call 00401060 ; 如果都符合就输出吧
00401038 |. 83C4 10 |||add esp, 10 ; 恢复堆栈
0040103B |> 46 |||inc esi ; k++
0040103C |. 83FE 05 |||cmp esi, 5
0040103F |.^ 7C DE ||\jl short 0040101F ; k<5则跳转
00401041 |. 47 ||inc edi ; j++
00401042 |. 83FF 05 ||cmp edi, 5
00401045 |.^ 7C D3 |\jl short 0040101A ; j<5则跳转
00401047 |. 43 |inc ebx
00401048 |. 83FB 05 |cmp ebx, 5
0040104B |.^ 7C C8 \jl short 00401015 ; i<5则跳转
0040104D |. 5F pop edi ; 恢复现场
0040104E |. 5E pop esi
0040104F |. 5B pop ebx
00401050 \. C3 retn
OD的那些跳转的连线还真给我们省事,一眼就能看出是三层循环。