1.需求

逆向工程师必须先是一个正向开发工程师,如果没有C++/MFC的开发经验,就不会懂得如何逆向分析C++/MFC的程序,本文完成一个helloworld的C++正逆向过程。

2.C++程序源码

编译环境:visual studio 2022

#include <iostream>
#include <cstdlib>
using namespace std;int main()
{int a;a = 100;for (int i = 0; i < a; i++){cout << "Hello World! " << endl;}cin >> a;return 0;}

编译完毕后生成exe程序,导入Ghidra,分析完毕后,在symbol tree窗口,输入main查找到主函数位置:

3.反编译结果

3.1 Ghidra反汇编

int __cdecl main(int _Argc,char **_Argv,char **_Env){basic_ostream<char,std::char_traits<char>_> *this;int iVar1;_RTC_framedesc *extraout_EDX;int *piVar2;code *pcVar3;int local_20 [4];int local_10 [2];uint local_8;piVar2 = local_20;for (iVar1 = 7; iVar1 != 0; iVar1 = iVar1 + -1) {*piVar2 = -0x33333334;piVar2 = piVar2 + 1;}local_8 = __security_cookie ^ (uint)&stack0xfffffffc;local_10[0] = 100;/* static local (stored at 004124a0) <NoType> static local (stored at 00412494) <NoType> static local (stored at 0041248c) <NoType> static local (stored at 004124a0) <NoType> static local (stored at 00412494) <NoType> static local (stored at 0041248c) <NoType> */for (local_20[1] = 0; local_20[1] < local_10[0]; local_20[1] = local_20[1] + 1) {pcVar3 = std::endl<char,std::char_traits<char>_>;this = std::operator<<<std::char_traits<char>_>((basic_ostream<char,std::char_traits<char>_> *)cout_exref,"Hello World! ");std::basic_ostream<char,struct_std::char_traits<char>_>::operator<<((basic_ostream<char,struct_std::char_traits<char>_> *)this,pcVar3);_RTC_CheckEsp();}std::basic_istream<char,struct_std::char_traits<char>_>::operator>>((basic_istream<char,struct_std::char_traits<char>_> *)cin_exref,local_10);_RTC_CheckEsp();iVar1 = 0;_RTC_CheckStackVars((void *)0x0,extraout_EDX);__security_check_cookie(local_8 ^ (uint)&stack0xfffffffc);local_8 = 0x412487;_RTC_CheckEsp();return iVar1;
}

3.2 IDA 结果

int __cdecl main()
{std::ostream *v0; // eaxint i; // [esp+D0h] [ebp-18h]int a; // [esp+DCh] [ebp-Ch] BYREFa = 100;for ( i = 0; i < a; ++i ){v0 = std::operator<<<std::char_traits<char>>(std::cout, "Hello World! ");std::ostream::operator<<(v0, std::endl<char,std::char_traits<char>>);}std::istream::operator>>(std::cin, &a);return 0;
}

4.Visual studio 里查看汇编代码

在正向开发的过程中,可以在编译器Visual studio里,查看C++代码的汇编代码,在程序中设置断点,F5编译,等程序停住后,才有查看汇编选项:

汇编代码如下:

--- C:\Users\paul\source\repos\helloc++\helloc++\helloc++.cpp ------------------1: // helloc++.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。2: //3: 4: #include <iostream>5: #include <cstdlib>6: using namespace std;7: 8: 9: int main()10: {
003F23D0 55                   push        ebp
003F23D1 8B EC                mov         ebp,esp
003F23D3 81 EC DC 00 00 00    sub         esp,0DCh
003F23D9 53                   push        ebx
003F23DA 56                   push        esi
003F23DB 57                   push        edi
003F23DC 8D 7D E4             lea         edi,[ebp-1Ch]
003F23DF B9 07 00 00 00       mov         ecx,7
003F23E4 B8 CC CC CC CC       mov         eax,0CCCCCCCCh
003F23E9 F3 AB                rep stos    dword ptr es:[edi]
003F23EB A1 04 C0 3F 00       mov         eax,dword ptr [__security_cookie (03FC004h)]
003F23F0 33 C5                xor         eax,ebp
003F23F2 89 45 FC             mov         dword ptr [ebp-4],eax  11:     int a;12:     a = 100;
003F23F5 C7 45 F4 64 00 00 00 mov         dword ptr [a],64h  13:     for (int i = 0; i < a; i++)
003F23FC C7 45 E8 00 00 00 00 mov         dword ptr [ebp-18h],0
003F2403 EB 09                jmp         __$EncStackInitStart+32h (03F240Eh)
003F2405 8B 45 E8             mov         eax,dword ptr [ebp-18h]
003F2408 83 C0 01             add         eax,1
003F240B 89 45 E8             mov         dword ptr [ebp-18h],eax
003F240E 8B 45 E8             mov         eax,dword ptr [ebp-18h]
003F2411 3B 45 F4             cmp         eax,dword ptr [a]
003F2414 7D 2B                jge         __$EncStackInitStart+65h (03F2441h)  14:     {15:         cout << "Hello World! " << endl;
003F2416 8B F4                mov         esi,esp
003F2418 68 3C 10 3F 00       push        offset std::endl<char,std::char_traits<char> > (03F103Ch)
003F241D 68 30 9B 3F 00       push        offset string "Hello World! " (03F9B30h)
003F2422 A1 DC D0 3F 00       mov         eax,dword ptr [__imp_std::cout (03FD0DCh)]
003F2427 50                   push        eax
003F2428 E8 7C ED FF FF       call        std::operator<<<std::char_traits<char> > (03F11A9h)
003F242D 83 C4 08             add         esp,8
003F2430 8B C8                mov         ecx,eax
003F2432 FF 15 A8 D0 3F 00    call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (03FD0A8h)]
003F2438 3B F4                cmp         esi,esp
003F243A E8 50 EE FF FF       call        __RTC_CheckEsp (03F128Fh)  16:     }
003F243F EB C4                jmp         __$EncStackInitStart+29h (03F2405h)  17:     cin >> a;
003F2441 8B F4                mov         esi,esp
003F2443 8D 45 F4             lea         eax,[a]
003F2446 50                   push        eax
003F2447 8B 0D 98 D0 3F 00    mov         ecx,dword ptr [__imp_std::cin (03FD098h)]
003F244D FF 15 9C D0 3F 00    call        dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::operator>> (03FD09Ch)]
003F2453 3B F4                cmp         esi,esp
003F2455 E8 35 EE FF FF       call        __RTC_CheckEsp (03F128Fh)  18:     return 0;
003F245A 33 C0                xor         eax,eax  19:     20: }
003F245C 52                   push        edx
003F245D 8B CD                mov         ecx,ebp
003F245F 50                   push        eax
003F2460 8D 15 8C 24 3F 00    lea         edx,ds:[3F248Ch]
003F2466 E8 C0 ED FF FF       call        @_RTC_CheckStackVars@8 (03F122Bh)
003F246B 58                   pop         eax
003F246C 5A                   pop         edx
003F246D 5F                   pop         edi
003F246E 5E                   pop         esi
003F246F 5B                   pop         ebx
003F2470 8B 4D FC             mov         ecx,dword ptr [ebp-4]
003F2473 33 CD                xor         ecx,ebp
003F2475 E8 02 ED FF FF       call        @__security_check_cookie@4 (03F117Ch)
003F247A 81 C4 DC 00 00 00    add         esp,0DCh
003F2480 3B EC                cmp         ebp,esp
003F2482 E8 08 EE FF FF       call        __RTC_CheckEsp (03F128Fh)
003F2487 8B E5                mov         esp,ebp
003F2489 5D                   pop         ebp
003F248A C3                   ret
003F248B 90                   nop
003F248C 01 00                add         dword ptr [eax],eax
003F248E 00 00                add         byte ptr [eax],al
003F2490 94                   xchg        eax,esp
003F2491 24 3F                and         al,3Fh
003F2493 00 F4                add         ah,dh
003F2495 FF                   ?? ??????
003F2496 FF                   ?? ?????? 19:     20: }
003F2497 FF 04 00             inc         dword ptr [eax+eax]
003F249A 00 00                add         byte ptr [eax],al
003F249C A0 24 3F 00 61       mov         al,byte ptr ds:[61003F24h]
003F24A1 00 CC                add         ah,cl  

5.小结

IDA反编译的结果更接近源程序,因为1.读取了pdb文件,2.不显示参数检查的反编译代码( __security_cookie和_RTC_CheckStackVars等)。

5.1 什么是security cookie

并不是windows系统自带的保护机制,并不是说一个确实存在溢出漏洞的程序,放到带security cookie保护的环境中,就不能正常溢出了。其原理是在所有变量入栈前,多压入一个变量(随机数),然后函数执行完之后,再去检查这个数是不是一样的,

5.2 什么是_RTC_CheckStackVars。

这也是一个编译器行为,_RTC_CheckStackVars第一个参数是函数要检查的栈顶地址,第二个参数指向结构体_RTC_framedesc。该结构体第一个参数是压栈的局部变量个数,第二个参数保存局部变量相关信息。分别是变量的栈偏移地址,变量大小和变量的名字。因此我们可以通过地址跳转最终找到出错的变量

C++程序正向编译逆向反编译(一)相关推荐

  1. 使用天乐软件加密狗(JDProtect)保护您的软件,防止程序被跟踪/逆向/反编译/破解

    作者:庄晓立(liigo) 日期:2011-4-8 原创链接:http://blog.csdn.net/liigo/archive/2011/04/08/6310677.aspx 转换请注明出处:ht ...

  2. 使用天乐软件加密狗(JDProtect)保护您的软件,防止程序被跟踪/逆向/反编译/破解...

    作者:庄晓立(liigo) 日期:2011-4-8 原创链接:http://blog.csdn.net/liigo/archive/2011/04/08/6310677.aspx 转换请注明出处:ht ...

  3. 《编译与反编译技术》—第1章1.7节C语言程序的编译流程

    本节书摘来自华章出版社<编译与反编译技术>一书中的第1章,第1.7节C语言程序的编译流程,作者庞建民,陶红伟,刘晓楠,岳峰,更多章节内容可以访问云栖社区"华章计算机"公 ...

  4. Python程序编译与反编译

    众所周知,Python是纯粹的自由软件, 源代码和解释器CPython遵循 GPL(GNU General Public License)协议.那么很自然会有人有这样的疑问:难道Python程序只能以 ...

  5. NP管理器 NPManager v3.0.49 安卓APK逆向反编译工具

    NP管理器 NPManager v3.0.49 安卓APK逆向反编译工具 NP管理器 NPManager 安卓反编译工具,NP管理器是一款强大的安卓反编译或反汇编工具,虽然这个NPManager反编译 ...

  6. 2020年 IOS 逆向 反编译 注入修改游戏或APP的调用参数新手系列教程——使用theos tweak 注入hook修改游戏执行代码上传动态头像

    2020年 IOS 逆向 反编译 注入修改游戏或APP的调用参数新手系列教程--使用theos tweak 注入hook修改游戏执行代码上传动态头像 开篇 需求&最终效果 环境要求与即将使用的 ...

  7. vue代码可以反编译吗_微信小程序源码提取反编译

    一.前言 微信小程序源码提取反编译,听起来很屌,其实还是简单的,基本是傻瓜式操作.要想拿到微信小程序源码,找到源文件在手机存放的位置就行,源文件拿到,用反编译脚本跑一下,微信小程序代码包里的所有文件. ...

  8. 《编译与反编译技术实战》——2.1节编译器、解释器及其工作方式

    本节书摘来自华章社区<编译与反编译技术实战>一书中的第2章,第2.1节编译器.解释器及其工作方式,作者刘晓楠 陶红伟 岳 峰 戴超,更多章节内容可以访问云栖社区"华章社区&quo ...

  9. 《编译与反编译技术》——第一章 引论 1.1节编译器与解释器

    本节书摘来自华章出版社<编译与反编译技术>一书中的第1章,第1.1节,作者庞建民,陶红伟,刘晓楠,岳峰.更多章节内容可以访问云栖社区"华章计算机"公众号查看. 人类之间 ...

最新文章

  1. 公元2019年,你对AI的信任有几分?
  2. php语言冒泡法,冒泡排序法(php)
  3. 数据图表与分析图_几种可视化数据分析图表的使用
  4. MySQL单机多实例部署详解之------多实例分别定义不同的配置文件
  5. 详解最短路算法模板(dijkstra+floyd+spfa)
  6. xpath定位中详解id 、starts-with、contains、text()和last() 的
  7. pandas dataframe 使用多进程apply(原生、pandarallel多进程、swifter多进程)
  8. 《巴伦周刊》评选出全球最佳30位CEO:马化腾再次上榜
  9. Web服务器(中间件)漏洞
  10. Android 屏幕刷新机制
  11. JavaSE面向对象-笔记
  12. Centos-shell-简介
  13. 电脑word在哪_永中PDF转WORD在线文档转换器——无需会员、没有限制
  14. 特殊矩阵——三对角矩阵(Tridiagonal Matrix)
  15. 易班登陆接口接入实例
  16. php实战视频教程 帝国cms二次开发,帝国cms7.5二次开发整合CKPlayer播放器教程
  17. 我安装archlinux的过程总结
  18. mac 文字识别软件ocr_Mac上那些好用的文字识别工具
  19. 在线靶场-墨者-安全意识1星-WEB页面分析
  20. 域名解析问题:聚名网域名该如何解析?有什么介绍吗?

热门文章

  1. 关于matlab中help无法使用的解决办法(点开后是空白)
  2. html遍历map,forEach()方法遍历map()方法数组遍历
  3. SSD的三组成部件简介:主控芯片 闪存芯片 固件算法
  4. stacking集成模型预测回归问题
  5. GBDT(梯度提升树)算法概述
  6. authorization权限控制_授权(Authorization)
  7. [935]python解析xml文件
  8. 讲解我在Ps(Adobephoto shop)中一个作品
  9. Windows命令行查看文件的MD5
  10. 【小白笔记】目标跟踪Deep Regression Tracking with Shrinkage Loss