反汇编 c++/c 确定main函数的位置

用OD加载文件的时候,不会停留在main函数上,如何确定main 的位置,这就需要对程序加载过程有个了解。

使用IDA就可以准确定位main 函数的起始位置。

void __cdecl start()
{
  DWORD v0; // eax@1
  int v1; // eax@4

  v0 = GetVersion();
  dword_4101A4 = BYTE1(v0);
  dword_4101A0 = v0;
  dword_41019C = BYTE1(v0) + (v0 << 8);
  dword_410198 = v0 >> 16;
  if ( !sub_4068EE(0) )
    fast_error_exit(0x1Cu);
  _ioinit();
  dword_411704 = *GetCommandLineA*();
  dword_41017C = __crtGetEnvironmentStringsA();
  _setargv();
  _setenvp();
  _cinit();
  dword_4101B8 = envp;
  v1 = main(argc, argv, envp);
  exit(v1);
}

可以看到,main函数开始之前,有很多的初始化工作。OD不会全部识别,唯一可以识别的函数是GetCommandLine,在此函数执行之后,一般要再次调用4个函数__crtGetEnviromentStrings、setargv、setenvp、cinit,此后才会执行main 函数。

因此,只要在GetCommandLine后跳过4个函数,一般就可以到达main 函数的位置。

如果你不想使用IDA加载程序来获得main函数位置,使用此方法可以快速找到main函数。是不是跳过4个,一般而言与编译器有很大的关系,所以,此方法只能算作经验积累。

时间: 2024-09-20 17:46:06

反汇编 c++/c 确定main函数的位置的相关文章

main函数的汇编代码

本文主要对main函数编译后生成的汇编码进行观察,为了简单起见,main函数的内容为空.实验方法如下:首先在不同环境下编译源代码,收集生成的可执行文件:随后将可执行文件使用IDA Pro(版本为5.5,这里赞一下强大的IDA!)进行反汇编:最后观察main函数的汇编码(所有汇编码格式都是Intel风格的),进行分析与比较.本文重点在于讨论一些最基本的概念,有助于读者熟悉各种环境生成的汇编码,更好地进行二进制分析.需要注意的是,在C语言的层面来看,main函数是程序的起始入口,但实际上对于可执行文

浅谈main函数的栈帧

要理解什仫是栈帧首先就要理解什仫是栈? 那仫什仫是栈呢?在数据结构中有一种结构叫栈,它的定义为:仅在表尾进行插入和删除的操作 我们允许插入和删除的一端称为栈顶(esp),另一端则为栈底(ebp),所以栈又被称为后进先出的线性表(LIFO).而且我们知道在内存中空间的分配是从高地址向低地址增长的; 好了说了这仫多的栈那仫什仫是栈帧呢?其实说白了栈帧实际上就是用来记录函数调用过程的信息,是编译器用来实现函数调用过程的的一种数据结构.下图是我对栈帧分布的一点理解,以下都是在VC++6.0版本下测试的:

带参数的main函数的使用

以前接触的main函数都是不带参数的.因此main 后的括号都是空括号.  main() {   ...  } 实际上,main函数可以带参数,这个参数可以认为是main函数的形式参数. C语言规定main函数的参数只能有两个,习惯上这两个参数写为argc和argv.因此,main函数的函数头可写为: main(argc,argv) C语言还规定argc(第一个形参)必须是整型变量,argv(第二个形参)必须是指向字符串的指针数组.加上形参说明后,main函数的函数头应写为: main (int

《Linux内核设计的艺术》学习笔记(一)从开机加电到执行main函数

  实验内核版本:0.11 ◆ 从开机到main函数的三步: ① 启动BIOS,准备实模式下的中断向量表和中断服务程序: ② 从启动盘加载OS程序到内存中,加载OS程序的工作就是利用第一步中的中断服务程序实现的: ③ 为执行保护模式下32位的main函数做过渡工作. ? Intel将所有80x86系列的CPU硬件都设计为加电即进入16位实模式状态运行: ? 将CPU硬件逻辑设计为在加电瞬间强行将CS置为0xFFFF,IP置为0x0000,即是CS:IP指向了0xFFFF0这个地址: 整个过程是一

《LINUX内核设计的艺术》第一章从开机家电到执行main函数之前的过程 学习笔记之一

从开机加电到实行main函数之前的过程 分为三步,目的是实现从启动盘加载操作系统程序,完成实现main函数的准备工作 启动BLOS,准备是模式下的中断向量表和中断服务程序 从启动盘加载操作系统程序到内存.加载操作系统程序就是靠第一步实现的 为实现32位的main函数做过度工作 1.1启动blos,准备实模式下的中断向量表和中断服务程序 由blos来加载软件操作系统的任务 1.1.1         BLOS的启动原理 0XFFFF0 由硬件来启动,CPU硬件设计逻辑设计为加电瞬间就强行将CS的值

【C语言】【笔试题】C语言main函数参数含义

#include <stdio.h> int main(int argc, char *argv[],char *envp[])//第一个参数argc只的是变量的个数,第二个参数值得是对应变量的位置,第三个指的是main函数中的所有环境变量 { int i = 0; for (i = 0; envp[i] != NULL; i++) { printf("%s\n", envp[i]); } if (strcmp(argv[1], "-a") == 0)

电脑从开机加电到操作系统main函数之前执行的过程

总的来说在操作系统加电启动之后到main函数执行之前操作系统经历了以下3个大步骤 1.启动BIOS.这个时候位于实模式下,加载中断向量和中断服务程序 2.加载操作系统内核并为保护模式做准备.这个时候操作系统一共加载了3部分代码:引导程序bootsect,内核代码setup,内核代码system模块 3.从实模式转换为32位保护模式.这个过程要做大量重建工作,并且持续工作到操作系统main函数的执行过程.细说的话,主要包括打开32位寻址空间,打开保护模式,建立保护模式下的中断相应机制与保护模式配套

【反汇编分析】C++成员函数和虚函数

本节通过反汇编研究C++非static成员函数和虚函数的执行流程: 代码片段如下 class Animal { public: virtual void print() { cout << "Animal::print "<< endl; } void print2() { cout << "Animal::print2 "<< endl; } }; class Dog : public Animal { public

[汇编与C语言关系]2. main函数与启动例程

为什么汇编程序的入口是_start,而C程序的入口是main函数呢?以下就来解释这个问题 在<x86汇编程序基础(AT&T语法)>一文中我们汇编和链接的步骤是: $ as hello.s -o hello.o $ ld hello.o -o hello 我们用gcc main.c -o main开编译一个c程序,其实际分为三个步骤:编译.汇编.链接 $ gcc -S main.c 生成汇编代码 $ gcc -c main.s 生成目标文件 $ gcc main.o 生成可执行文件 我们