学习C/C++快有两年了,现在想系统学习下逆向工程(反汇编),找来找去最终选定了 《天书夜读-从汇编语言到Windows内核编程》 这本书,看了两章感觉很不错,决定深入学习下去。可是课后的思考题没有答案,下面是我自己练习过程中自写的代码(答案),提供给网友们参考,有不对之处还请指正,谢谢!
第二章C语言的流程和处理 (2.2思考题)
// pritices1.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" int myfunction(int a,int b) { int d = a+b; int i,c; i=1; c=0; while(c< 100) { c = c+i; } switch(c) { case 0: d=1; d =c; break; case 1: d=c; break; default: d=0; } return d; } int _tmain(int argc, _TCHAR* argv[]) { int retval=myfunction(3,4); return 0; }
第三章 3.3(汇编反C语言练习)
00401000 push ecx F 00401001 mov ecx,dword ptr [esp+10h] D ecx=b 00401005 mov edx,dword ptr [esp+8] D edx=a 00401009 push ebx F 0040100A mov ebx,dword ptr [esp+18h] D ebx=d 0040100E push esi F 0040100F mov esi,dword ptr [esp+14h] D esi=c 00401013 push ebp F 00401014 xor eax,eax C eax=0 00401016 push edi F 00401017 jmp myfunction+20h (004020h) C 00401019 lea esp,[esp] C 00401020 mov edi,dword ptr [esi+8] D edi=c[2] 00401023 imul edi,dowrd ptr [edx+eax*8+4] D edi*=a+eax*8+4 <=> edi=c[2]*a[eax*2+1] 00401028 mov ebp,dowrd ptr [esi] D ebp=c[0] 0040102A imul ebp,dword ptr [edx+eax*8] D ebp*=a+eax*8 <=> ebp=c[0]*a[eax*2] 0040102E add edi,ebp D edi=edi+ebp <=> edi=c[2]*a[eax*2+1]+c[0]*a[eax*2] 00401030 mov dword ptr [ecx],edi D b[0]=edi <=> b[0]=c[2]*a[eax*2+1]+c[0]*a[eax*2] 00401032 mov edi,dword ptr [esi+0ch] D edi=c[3] 00401035 imul edi,dword,ptr [edx+eax*8+4] D edi*=a[eax*2+1] <=> edi=c[3]*a[eax*2+1] 0040103A mov ebp,dword ptr [esi+4] D ebp=c[1] 0040103D imul ebp,dword ptr [edx+eax*8] D ebp*=a[eax*2] <=> ebp=c[1]*a[eax*2] 00401041 add edi,ebp D edi=edi+ebp <=> edi=c[3]*a[eax*2+1]+c[1]*a[eax*2] 00401043 mov ebp,dword ptr [ecx] D ebp=b[0] 00401045 add ebp,edi D ebp=ebp+edi <=> ebp=b[0]+c[3]*a[eax*2+1]+c[1]*a[eax*2] 00401047 add ebx,ebp D ebx=ebx+ebp <=> ebx=d+b[0]+c[3]*a[eax*2+1]+c[1]*a[eax*2] 00401049 mov dword ptr [ecx+4],edi D b[1]=edi <=>b[1]=c[3]*a[eax*2+1]+c[1]*a[eax*2] 0040104C inc eax C eax++ 0040104D add ecx,8 D ecx=ecx+8 00401050 cmp eax,2 C 00401053 jl myfunction+20h(401020h) C for(i=0;i<2;i++) { b[i]=c[2]*a[i*2+1]+c[0]*a[i*2] b[i+2]=c[3]*a[i*2+1]+c[1]*a[i*2] } switch(d[0]+b[0]+i) { case 100: printf("cnt is 110"); case 110: printf("cnt is 110"); default: printf("nothing"); } return d[0]+b[0]+i; 00401055 call rand(401138h) C 0040105A add ebx,eax D d=d+eax 0040105C cmp ebx,64h C 0040105F pop edi F 00401060 pop ebp F 00401061 je myfunction+7Bh(40107Bh) C 00401063 cmp ebx,6Eh C 00401066 je myfunction+88h(401088h) C 00401068 push offset string "nothing" (40711h) F 0040106D call printf (402207h) C 00401072 add esp,4 C 00401075 pop esi 00401076 mov eax,ebx 00401078 pop ebx 00401079 pop ecx 0040107A ret 0040107B push offset string "cnt is 110" (4070FCh) 00401080 call printf (401107h) 00401085 add esp,4 00401088 push offset string "cnt is 110" (4070FCh) 0040108D call printf (401107h) 00401092 add esp,4 00401095 pop esi 00401096 mov eax,ebx 00401098 pop ecx 0040109A ret
我反汇编出来的代码,和书中并非完全一样
// tl17.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <stdlib.h> int myfunction(int a[],int b[],int c[],int d) { int i,r,h; i=0; for(i=0;i<2;i++) { b[i]=c[2]*a[i*2+1]+c[0]*a[i*2]; b[i+1]=c[3]*a[i*2+1]+c[1]*a[i*2]; } r=rand(); h=r+d+b[i]+c[3]*a[i*2+1]+c[1]*a[i*2]; switch(h) { case 100: printf("cnt is 110"); case 110: printf("cnt is 110"); default: printf("nothing"); } return h; } int _tmain(int argc, _TCHAR* argv[]) { int a[3],b[3],c[3],d; d=5; myfunction(a,b,c,d); return 0; }