首页 > 其他分享 >x64逆向——MT、MT在release和debug下的四种模式寻找main入口

x64逆向——MT、MT在release和debug下的四种模式寻找main入口

时间:2023-04-22 15:13:22浏览次数:41  
标签:调用 x64 DLL MT exit 寻找 debug main

vs代码生成四种模式:

MT选项:链接LIB版的C和C++运行库。在链接时就会在将C和C++运行时库(LIBCMT.LIB、LIBC.LIB)集成到程序中,程序体积会变大。
MTd选项:LIB的调试版。
MD选项:使用DLL版的C和C++运行库,这样在程序运行时会动态的加载对应的DLL,程序体积会减小,缺点是在系统没有对应DLL时程序无法运行(需添加MSVCPxx.DLL、MSVCRxx.DLL)。
MDd选项:表示使用DLL的调试版。
带T的链接静态库lib;带D链接动态库dll;带d为调试版本,库名加d

 

例如我的机器上搜索,vs2022里有libcmt,但是libc.lib只有vc6才有:

 因此,寻找main的入口函数,需要针对四种模式进行区分:

x64里main三个参数,call之后就是exit,因此寻找的方式:直接寻找exit最近的一个包含ecx、rdx、r8的三个参数的call调用就是main了:

 

举例:

#include <stdio.h>

int main(int argc, char* argv[], char* env[])
{
    return 0;
}

1、debug模式: 多线程调试 DLL (/MDd) 寻找main:

我使用vs2022生成的exe,在ida 7.5里使用上述思路寻找main:

 

 第一个exit上面,有2个call都可能是main,为了看里面是否有三个参数,点击进去:

第一个sub_140011C20,双击进去:

可以确定它就是main调用了。

当然,另外一个不是,如下图所示:

 

 

2、Release模式: 多线程 DLL (/MD)寻找main:

思路基本上和上面1是一样的,但是更加简洁,可以直接在exit上面看到call main:

 

如果是动态调试呢?如何快速找到main:

在xdb里打开,使用符号搜索exit,然后在该处设置断点,然后运行程序到断点处,查看调用栈,这样就可以快速识别到main了。

 

符号搜索exit,注意是在urcrtbase.dll里搜索:

 跳转到该处,设置断点:

 运行到该处:

 查看调用堆栈:

 然后双击test.$...那个,可以看到返回地址对应下面图中的nop,上面调的call是test.exit,也就是他里面调用的ucrtbase的cexit了!

 向上找,是不是就可以找到包含三个参数的test main调用了!!!

 

如果是上面1的debug模式,要在xdb里寻找main,思路和上面类似,但是有区别:

在test.exe搜索exit,调用的是ucrtbase.exit 设置断点,然后看调用stack,追到如下位置:

 然后看上面的几个call,哪个是main?一一点击进去就可以看到是最上面的第二个call了!如下看到了3个参数的main调用:

 

总结下来:

多线程dll模式寻找main通过用符号搜索的方法先找到exit再到附近函数寻找三个参数的main方法还是比较容易操作的。注意release是可以直接看到三个参数的main,而debug是要进入到函数里面才可以看到。

 

重要说明:

 

之所以IDA可以直接找到main,是因为IDA是通过arc和argv的dll调用发现了main的,如下:

 

而如果使用了静态链接,也就是MT方式的话,如下图所示,那么IDA是无法找到main的!!!这个时候定位到main的话,就需要另外的方式了。

 

 

这个时候,就需要使用sigmake生成sig签名文件,让ida可以根据签名寻找函数名了。

3、debug模式: 多线程调试 (/MTd)寻找main:

ida里生成sig文件方法:将需要生成sig文件的lib放在flair75文件夹下,然后运行下面的几个命令:

具体参考这个文章:https://www.freesion.com/article/65491420550/

注意:冲突的时候需要编辑这个.exc文档,将前面几行的注释删除,下面有冲突的函数签名,选择一个,前面加上'+',保存即可。 然后,重新运行sigmake工具,sigmake会自己读取修改以后的.exc文件,生成sig文件。

 

然后我的ida里代码终于成如下模样了:

 

 

 

这里比较难的是如何在xdb里寻找到main。看符号和callstack已经比较繁琐了。

在test.exe里搜索exit,找到exitprocess调用,设置断点:

运行, 然后观察调用stack:

 

向上走了2,3级才看到下面真正的main,也是很蛋疼:

 

 

4、release模式:多线程 (/MT)寻找main:

同上,ida里也需要制作sig文件。

总之呢,static方式链接的exe要找main还是比较复杂,需要较多的工程经验。即便是看到了exit,也需要向上捣腾好几级,在进入附近的函数(甚至还继续点击进去)才能够找到main。

 

标签:调用,x64,DLL,MT,exit,寻找,debug,main
From: https://www.cnblogs.com/bonelee/p/17343111.html

相关文章

  • 用 GODEBUG 看调度跟踪
    用GODEBUG看调度跟踪让Go更强大的原因之一莫过于它的GODEBUG工具,GODEBUG的设置可以让Go程序在运行时输出调试信息,可以根据你的要求很直观的看到你想要的调度器或垃圾回收等详细信息,并且还不需要加装其它的插件,非常方便,今天我们将先讲解GODEBUG的调度器相关内容,希望对......
  • 加密与解密x64逆向——寄存器和函数调用
    64位软件逆向技术寄存器本节讨论的x64是AMD和INTEL64的合成,是指与现有x86兼容的64位CPU。在64位系统中,内存地址为64位。x64系统通用寄存器的名称,第一个字母从E改为R“RAX”,大小扩展到64位,数量增加8个,扩充了8个128位XMM寄存器。函数1.栈平衡RSP用来保存当前的栈顶指针,每8个......
  • 加密与解密x64逆向——变量、if和switch、循环语句
    数据结构主要是对局部变量,全局变量,数组等的识别。1.局部变量局部变量是函数内定义的变量,存放的内存区域称之为栈区。生命周期就是从函数进入到返回释放。函数在入口处申请了预留栈空间和局部变量空间,也就是subrsp,30h。局部变量空间在高地址。在应用程序被编译成release版本......
  • 加密与解密x64逆向——虚函数
    4.整数的取模取模运算可以通过除法指令实现。一般的优化做法是将其转换成等价的位运算或者除法运算,再由除法运算进行优化。虚函数C++的三大核心机制是封装,继承,多态,而虚函数就是多态的一种体现。软件逆向中,难免遇到使用面向对象思想设计的软件,而虚函数就是在实际软件逆向过程中......
  • 【逆向】x64程序逆向基础——调用约定和栈使用
    【逆向】x64程序逆向基础 主要区别1.所有地址指针都是64位。2.增加和扩展新的寄存器,并兼容原32位版本的通用寄存器。3.原指令指针寄存器EIP扩展为RIP。寄存器1.64位寄存器兼容原32位寄存器。2.新增加8个XMM寄存器(XMM8-XMM15)。3.扩展原32位寄存器的64位版本,并......
  • idea实现远程debug汇总
    idea实现远程debug,这个很实用的,可以实现发现并解决测试环境有问题,本地环境没有问题的情况。原理其实就是请求的时候远程的服务打到本地的,其实就是解决测试环境有问题,无法解决,需要通过本地debug的形式发现问题,这个其实很好用。参考博客:https://www.ngui.cc/el/1611042.html?action=......
  • 邮箱伪造之搭建匿名SMTP服务器
      电子邮件欺骗(emailspoofing)的根本原因是SMTP协议是不需要身份验证的,攻击者可以利用这个特性伪造电子邮件头,从任意电子邮件地址发送任何人,导致信息看起来来源于某个人或某个地方,而实际却不是真实的源地址。   如果要实现邮箱伪造发件人地址,首先,我们需要一个可以用来发送......
  • eclipse debug source not found
    eclipse开发过程进行debug时提示“Sourcenotfound”,无法进行正常的debug编译。可以使用以下方法解决 1.错误页面上有个链接addprojectpath(具体名称忘记了),点击进去,然后再添加自己的项目进入。 2.Windows-Preference-Java-Compiler。找到addsourcefilenametog......
  • ArcGIS API for JavaScript 4.x加载GeoServer发布的WMTS服务
    前言 以前用OpenLayers加载GeoServer我记得很简单,现在用ArcGISAPI加载捣鼓了一天没搞好,第二天早上来参考一篇文章搞好了,我这纯属记录下。背景 客户没有ArcGISServer的许可,所以就只能用GeoServer发布或者离线切片,先研究下GeoServer,后面如果心情好再研究下离线切片。......
  • .NET中Debug模式与Release模式
     一、Debug和Release的区别Debug:调试版本,包含调试信息,所以容量比Release大很多,并且不进行任何优化(优化会使调试复杂化,因为源代码和生成的指令间关系会更复杂),便于程序员调试。Debug模式下生成两个文件,除了.exe或.dll文件外,还有一个.pdb文件,该文件记录了代码中断点等调试信息......