C++程序正向编译逆向反编译(一)

这篇具有很好参考价值的文章主要介绍了C++程序正向编译逆向反编译(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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查找到主函数位置:

c++反编译,物联网信息安全,安全,网络安全

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; // eax
  int i; // [esp+D0h] [ebp-18h]
  int a; // [esp+DCh] [ebp-Ch] BYREF

  a = 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++反编译,物联网信息安全,安全,网络安全

 汇编代码如下:

--- 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。该结构体第一个参数是压栈的局部变量个数,第二个参数保存局部变量相关信息。分别是变量的栈偏移地址,变量大小和变量的名字。因此我们可以通过地址跳转最终找到出错的变量文章来源地址https://www.toymoban.com/news/detail-798672.html

到了这里,关于C++程序正向编译逆向反编译(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 机械臂正向与逆向运动学求解

            机械臂的正运动学求解即建立DH参数表,然后计算出各变换矩阵以及最终的变换矩阵。逆运动学求解,即求出机械臂各关节θ角与px,py,pz的关系,建立θ角与末端姿态之间的数学模型,在这里以IRB6700为例,对IRB6700进行正逆运动学求解和验证。 目录 正运动学求解 逆

    2023年04月10日
    浏览(29)
  • Linux C++性能优化秘籍:从编译器到代码,探究高性能C++程序的实现之道

    随着大数据、人工智能等技术的飞速发展,程序性能优化的重要性愈发突出。优化性能可以降低资源消耗、提高系统响应速度,从而在有限的硬件资源下,实现更高的吞吐量和处理能力。此外,性能优化也有助于降低能耗、减少散热问题,延长硬件使用寿命。 Linux操作系统具

    2023年04月09日
    浏览(36)
  • 在C++中控制调试信息的输出通常通过预处理指令(如 #define)和条件编译指令(如 #ifdef、#ifndef、#endif)来实现。

    在C++中,控制调试信息的输出通常通过预处理指令(如 #define )和条件编译指令(如 #ifdef 、 #ifndef 、 #endif )来实现。这种方法提供了一种灵活的方式来包含或排除调试代码,而无需对代码本身进行大量修改。以下是实现这一功能的一种常见方法: 定义一个宏用于控制调试

    2024年02月02日
    浏览(30)
  • vscode开发c++ 程序,配置使用微软自家的cl编译器。

    vscode 写c++代码, 配置为使用微软自己的cl编译器: 1.安装visual studio 2022, 并且创建一个可以正常编译的cpp工程。 2. 从visual studio 2022的菜单 项目 属性,查出include和lib的配置信息,并录入到window的系统环境变量中,当然还要把cl可执行文件的路径也录入到window11系统PATH中,如下

    2024年03月19日
    浏览(50)
  • 分词算法----正向和逆向最大匹配算法(含Python代码实现)

    分词算法(Segmentation Method) 在文本处理流程中,对语句进行分词(Segmentation)操作对于计算机认识并理解人类语言是基础且重要的。 对于中文来讲,不同于英文直接采用空格符进行分隔,并且中文词语内涵丰厚,语义丰富,所以只有采用合适的分词算法,才能准确迅速地向计

    2024年03月25日
    浏览(41)
  • 利用逆向工具反编译溯源小程序

    以下为逆向过程工具,下载后无需安装直接使用。 逆向工具使用的是:wxappUnpacker 解密工具使用的是以上工具包中的: 使用PC版微信客户端的小程序模块,查找客户端的文件保存目录 Applet目录即为存放小程序编译包的路径。如果此目录下有多个文件夹无法区分建议把wx开头的

    2024年04月13日
    浏览(28)
  • 微信小程序逆向反编译获取源码

    node环境 node官网 微信开发者工具 下载地址 小程序包 逆向工具 GitHub UnpackMiniApp.exe 解密小程序包工具 wxpack 存放解密后的小程序包(.wxapkg文件)与小程序源码文件(与小程序包同名) Unpacker 反编译脚本,将解密后的小程序包(.wxapkg文件)反编译为小程序源码文件 博客:原地

    2024年02月20日
    浏览(41)
  • 滴水逆向三期笔记与作业——02C语言——05 正向基础/05 循环语句

    原理:arr[5]是ebp的位置,而arr[6]是ebp+0x4的位置,即函数的返回地址,赋值给arr[6]相当于是修改了eip寄存器。 反汇编:i等于7时,修改了rbp+0x1c-0x20即rbp-0x4位置的值,将其置为0,而该位置为i的值,所以每一轮for过后将i重新置0,就造成了不停的循环。 声明一个变量就是告诉计

    2024年02月15日
    浏览(43)
  • 微信小程序 Spdier - OfferShow 反编译逆向(一)

    本文需要使用到的工具有: Charles抓包工具、夜神模拟器、微信开发者工具、wxapkg反编译工具CrackMinApp; 提示:需要安装好Charles和夜神模拟器并配置好App抓包环境,以及安装好微信开发者工具 / 反编译工具CrackMinApp Charles夜神模拟器安装教程:https://blog.csdn.net/EXIxiaozhou/article

    2024年01月17日
    浏览(33)
  • Clion配置C++程序用Android NDK编译,并用真机远程调试(临时目录和termux)

    :ndk, clion, cmake, usb, tcp, ssh, remote debug, remote gdb debug, termux, tabby 假设已经有了一个在windows下能正常编译运行的C++控制台程序,本文仅说明如何在windows下交叉编译到android并调试。C++库类似。 要点提示: 对于unity用户,建议用unity 2022自带的 ndk r23 。理论上可以用新版,但

    2024年02月21日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包