马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
我写的代码对源代码稍微做了点修饰,这样想自己好表达一些, 而且方便深入点。 // tsyd01.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> //增加1个输出输入流的头文件 myfunction(double a, double b) //来分析这个函数 { double c = a + b; return c; } int main(int argc, char* argv[]) { double Number1, Number2; //定义2个变量 std::cout << "Please enter the two numbers add up !\n\n"; //输入提示语 std::cin >> Number1 >>Number2; //接收2个变量 std::cout << "Number1 + Number2 = " << myfunction(Number1,Number2); //输入函数 std::cin.ignore(100, '\n'); //停止一会,看下结果 std::cin.get(); return 0; } VC反汇编 我们的myfunction函数 1: // tsyd01.cpp : Defines the entry point for the console application. 2: // 3: 4: #include "stdafx.h" 5: #include <iostream> //增加1个输出输入流的头文件 6: 7: myfunction(double a, double b) //来分析这个函数 8: { 00401A50 push ebp //保存ebp 00401A51 mov ebp,esp //把esp保存到ebp中,这样esp和ebp都是栈顶 00401A53 sub esp,48h //esp往上开辟一段空间,来存储我们的局部变量 00401A56 push ebx //保存ebx, esi, edi 00401A57 push esi 00401A58 push edi 00401A59 lea edi,[ebp-48h] //取[ebp-48h](局部变量)的地址,取局部变量地址保存 00401A5C mov ecx,12h 00401A61 mov eax,0CCCCCCCCh 00401A66 rep stos dword ptr [edi] //上面的都写入int 3中断 9: double c = a + b; 00401A68 fld qword ptr [ebp+8] //压一个浮点数入栈 b00401A6B fadd qword ptr [ebp+10h] //加上另一个浮点数, 这里面应该有一个隐含的装载过程 00401A6E fst qword ptr [ebp-8] //float的强制转换. 这里它另外使用了内存 10: return c; 00401A71 call __ftol (0040b43c) 11: } 00401A76 pop edi //返回我们的推栈,操作还原 00401A77 pop esi 00401A78 pop ebx 00401A79 mov esp,ebp //还原栈顶 00401A7B pop ebp 00401A7C ret 在看下main函数这个和第一篇的main函数开头是一样的
13: int main(int argc, char* argv[]) 14: { 00401A90 push ebp //操作保存ebp 00401A91 mov ebp,esp //将栈顶指针给ebp 00401A93 sub esp,50h //向上开辟一段空间 00401A96 push ebx //保存ebx 00401A97 push esi //保存esi 00401A98 push edi //保存edi 00401A99 lea edi,[ebp-50h]//将ebp-50h的地址给edi 00401A9C mov ecx,14h //ecx = 14 (循环14次) 00401AA1 mov eax,0CCCCCCCCh //int 3 中断 00401AA6 rep stos dword ptr [edi] //循环开辟10次int 3中断 15: 16: double Number1, Number2; //定义2个变量 17: std::cout << "Please enter the two numbers add up !\n\n"; //输入提示语 00401AA8 push offset string "Please enter the two numbers add"... (00472038) //保存我们的字符串 00401AAD push offset std::cout (004800c0) //在保存我们的输出流从右往左保留顺序 00401AB2 call @ILT+965(std::operator<<) (004013ca) //调用输出我也不知道为什么这样做, 估计是编译器的缘故把,或者我的理解是错的 00401AB7 add esp,8 //推栈平衡 18: 19: std::cin >> Number1 >>Number2; //接收2个变量 00401ABA lea eax,[ebp-10h] //ebp-10的地址给eax 00401ABD push eax //保存地址Number2 00401ABE lea ecx,[ebp-8] //在把ebp-8的地址给ecx 00401AC1 push ecx //保存地址Number1 00401AC2 mov ecx,offset std::cin (00480150)//在此我认为是为我们输入的分配空间ecx 估计是debug的缘故,等下看下发行版的和OD看下就知道了。 00401AC7 call @ILT+630(std::basic_istream<char,std::char_traits<char> >::operator>>) (0040127b) //然后开始接收第一个输入 00401ACC mov ecx,eax //把输入的传送到ecx中 00401ACE call @ILT+630(std::basic_istream<char,std::char_traits<char> >::operator>>) (0040127b) //在接收我们的输入 20: 21: std::cout << "Number1 + Number2 = " << myfunction(Number1,Number2); //输入函数 00401AD3 mov edx,dword ptr [ebp-0Ch] //保存寄存器操作 00401AD6 push edx 00401AD7 mov eax,dword ptr [ebp-10h] 00401ADA push eax 00401ADB mov ecx,dword ptr [ebp-4] 00401ADE push ecx 00401ADF mov edx,dword ptr [ebp-8] 00401AE2 push edx 00401AE3 call @ILT+730(myfunction) (004012df) //调用我们的函数myfunction 00401AE8 add esp,10h //推栈平衡 00401AEB push eax //保存eax寄存器,在这里我很费解,这里的eax不是int 3中断的么?还保存。。。 00401AEC push offset string "Number1 + Number2 = " (0047201c) //保存函数计算出来的结果 00401AF1 push offset std::cout (004800c0) //保存我们的输出 00401AF6 call @ILT+965(std::operator<<) (004013ca) //调用输出 00401AFB add esp,8 //推栈平衡 00401AFE mov ecx,eax 00401B00 call @ILT+340(std::basic_ostream<char,std::char_traits<char> >::operator<<) (00401159) //输出我们想输出的 22: 23: std::cin.ignore(100, '\n'); //停止一会,看下结果 00401B05 push 0Ah //保存\n 00401B07 push 64h //保存100 00401B09 mov ecx,offset std::cin (00480150) //把输入传递给ecx 00401B0E call @ILT+540(std::basic_istream<char,std::char_traits<char> >::ignore) (00401221) //调用要我们输入 24: std::cin.get(); 00401B13 mov ecx,offset std::cin (00480150) //把输入的给ecx 00401B18 call @ILT+410(std::basic_istream<char,std::char_traits<char> >::get) (0040119f) //检测看是否输入正确 25: return 0; 00401B1D xor eax,eax //清空eax 26: } 00401B1F pop edi //弹出edi, esi, ebx, 还原我们的开辟空间,还原我们的栈顶, 最后返回 00401B20 pop esi 00401B21 pop ebx 00401B22 add esp,50h 00401B25 cmp ebp,esp 00401B27 call __chkesp (0040b230) 00401B2C mov esp,ebp 00401B2E pop ebp 00401B2F ret 在此,自己对debug版的稍微分析了下,自己水平有限,由于自己vc也用的不好,不会查看推栈和寄存器,没人教- - 。。。 在来用OD看下debug的 代码是这样的。核对下vc的。差不多。。 所以只能从发行版的,在来用od入手,把这段代码尽自己能力在多分析下了 OD进入发行版 由于自己研究的,如果有人看到我的手记愿意和我交流下怎么逆向,还有些工具使用方法啊,心得啊,那是最好的了。 我找到代码的领空是这样的办法的 限制字数!!!!!我发我的草稿文件把,完整版本的啊!!!. . 2012/04/02 晚上 |