首先写一个很简单的main函数:

  1. int main(){
  2. printf("main的地址(?):%08x",main);
  3. }

单步调试,可得知 main函数的真实入口地址是:00be91a0

然而我们控制台输出的值是

为什么会出现这样的差别呢?院子里有一篇大牛写的有关注入的文章:http://www.cnblogs.com/fanzhidongyzby/archive/2012/08/30/2664287.html,里面就提到了这个问题。

其中提到一个解析真实地址的算法:

  1. //将函数地址转换为真实地址
  2. unsigned int getFunRealAddr(LPVOID fun)
  3. {
  4. unsigned int realaddr = (unsigned int)fun;//虚拟函数地址
  5. // 计算函数真实地址
  6. unsigned char* funaddr = (unsigned char*)fun;
  7. if (funaddr[] == 0xE9)// 判断是否为虚拟函数地址,E9为jmp指令
  8. {
  9. int disp = *(int*)(funaddr + );//获取跳转指令的偏移量
  10. realaddr += + disp;//修正为真实函数地址
  11. }
  12. return realaddr;
  13. }

相信新手朋友都和我一样为这段代码怎么来的摸不着头脑。特此我单步调试研究了一番,才大致明白原理:

main函数名的地址其实就是一个 Jmp xxx的指令,

从vs的反汇编调试代码可以看出,第一个参数main入栈,对应汇编代码就是 push 0be135Ch ,这个入栈的数字,其实就是刚刚控制台输出的那个地址。所以很显然这个地址就是函数main的“函数名”所在的地址(其实在汇编里应该是不存在 “main”这样的字符串的,之所以可能可以在vs或在od这样的调试器里看到,是这些调试器通过经验推断出来的结果。)。然后 我们在地址栏里输入 0be135Ch这个地址,就可以跳到 相对的位置处。

jmp 对应的汇编码为 E9, 而后面的4个字节"3F 7E 00 00",实际上是倒序的相对地址 0x00007e3f.也就是我们看到是main。当然这个地址只是代码的相对位置,如果运行之后,就要加上当前模块的基址才是绝对地址。

那么既然,这个“main”的位置只是一个跳转指令(JMP),肯定是跳转到了jmp后面跟的这个地址的位置了,也就是说这个地址就是真正的main函数的地址了。

当然,0be135Ch是从e9 3F 7E 00 00这条指令开始算的。也就是说,从e9 3F 7E 00 00的位置开始算,跳过去0x00007e3f个字节,就到了真正的main函数入口处。

所以真正的地址就是

0be135Ch+5(指令占的字节数 JMP main)+0x00007e3f=00be91a0.

所以我们再回到函数部分来。

  1. UINT realaddr = (UINT)main;// 拆箱转换成 unsigned int 数据。代表main函数名所代表的地址
  2. unsigned char* funcaddr = (UCHAR*)main; //这里是获取main地址所在的字节内容,其内容为“e9 3F 7E 00 00”(JMP main),所以只要判断前面的字节指令是否是e9就知道是不是真实地址了,如果是Jmp(e9)的话就不是真正的地址。
  3. if (funcaddr[] == 0xE9){ //因为
  4. UCHAR* fa = funcaddr + ;//指针移后一位,从e9到 3f.
  5. int* as = (int*)(fa); //取指针=处的int数据(共4个字节),实际上这里就是一个跳转地址。
  6. int disp = *as; //取指针的内容
  7. realaddr += + disp;//在main地址的基础上+JMP main所占的字节+要正向跳转的字节数
  8. }

vc 获取函数名称真实地址的更多相关文章

  1. JavaScript函数之实际参数对象(arguments) / callee属性 / caller属性 / 递归调用 / 获取函数名称的方法

    函数的作用域:调用对象 JavaScript中函数的主体是在局部作用域中执行的,该作用域不同于全局作用域.这个新的作用域是通过将调用对象添加到作用域链的头部而创建的(没怎么理解这句话,有理解的亲可以留 ...

  2. 利用PE数据目录的导入表获取函数名及其地址

    PE文件是以64字节的DOS文件头开始的(IMAGE_DOS_HEADER),接着是一段小DOS程序,然后是248字节的 NT文件头(IMAGE_NT_HEADERS),NT的文件头位置由IMAGE_ ...

  3. web服务器获取请求客户端真实地址的方法

    服务器获取客户端或者网页的请求,获取IP时需要注意,因为一个请求到达服务器之前,一般都会经过一层或者多层代理服务器,比如反向代理服务器将http://192.168.1.10:port/ 的URL反向 ...

  4. NodeJs获取函数名称和函数操作整理

    var aa = function () { log("xxxx"); }; aa(); var model = {}; model.test = function () { lo ...

  5. VC 获取多个mac地址

    转载请注明来源:https://www.cnblogs.com/hookjc/ #include <IPHlpApi.h>#include <iostream>#pragma ...

  6. 【Python】—— 获取当前运行函数名称和类方法名称

    原文出处: python笔记19-获取当前运行函数名称和类方法名称 获取函数名称 1.在函数外部获取函数名称,用.__name__获取 2.函数内部获取当前函数名称,用sys._getframe(). ...

  7. python笔记19-获取当前运行函数名称和类方法名称

    前言 写完代码之后,一般为了方便查看日志,可以在日志输出中加入当前运行的函数名称或类和方法名称,以便于代码报错的时候能快速找到报错的是哪个函数或方法. 那么如何获取当前运行函数(或方法)的名称呢? 获 ...

  8. 基于WMI获取本机真实网卡物理地址和IP地址

    using System; using System.Collections.Generic; using System.Management; using System.Runtime.Intero ...

  9. 旧书重温:0day2【4】动态获取函数地址

    通过以上3篇文章的学习,我们已经可以获取到kernel32.dll的地址了下一步 我们就是获取几个重要的函数 1.GetProcAddress 2.LoadLibrary 有了这两个函数很多函数都可以 ...

随机推荐

  1. Codeforces 1082 B. Vova and Trophies-有坑 (Educational Codeforces Round 55 (Rated for Div. 2))

    B. Vova and Trophies time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  2. CodeForces 738C Road to Cinema

    二分答案. 油量越多,显然通过的时间越少.可以二分找到最小的油量,可以在$t$时间内到达电影院. 一个油箱容量为$v$的车通过长度为$L$的路程需要的最小时间为$max(L,3*L-v)$.计算过程如 ...

  3. CodeForces 734F Anton and School

    位运算. 两个数的和:$A+B=(AandB)+(AorB)$,那么$b[i]+c[i]=n*a[i]+suma$.可以解出一组解,然后再按位统计贡献验证一下. #pragma comment(lin ...

  4. logging模块介绍

    在我们的实际开发过程中,我们有时候需要记录一些重要操作,或者程序运行情况,我们就需要在程序里面写入日志,来达到更快的排错跟记录重要操作的目的.在Python中logging模块就很好的解决了这个问题, ...

  5. HTTP Slow Attack测试工具SlowHTTPTest

    HTTP Slow Attack测试工具SlowHTTPTest   Slow Attack是HTTP常见的一种拒绝服务攻击方式.它通过消耗服务器的系统资源和连接数,导致Web服务器无法正常工作.常见 ...

  6. CodeForces - 992D Nastya and a Game

    题面在这里! 显然一段区间的 mul - sum * k = 0 才合法,然鹅我们发现sum * k 对于本题的数据来说最大才是1e18,也就是说mul必须得<=1e18. 我们不妨从这里入手, ...

  7. 【Java】【高精度】【递推】UVA - 11375 - Matches

    d[i+c[j]]+=d[i](c[j]是拼成j所需的火柴数) d[0]=1: 别忘了不能有前导零,所以当i为零时,不要尝试去拼成零.反而应该在n>=6时,最后给答案加1(单独拼出0). imp ...

  8. 条件注释判断浏览器<!--[if !IE]>

    <!--[if !IE]><!--> 除IE外都可识别 <!--<![endif]--><!--[if IE]> 所有的IE可识别 <![e ...

  9. 连接mysql时1045错误的解决办法

    重装系统后,今天mysql提示1045错误无法连接上,找了很久得出方法如下: 修改root密码即可正常. 1,进入mysql控制台选择: 2,use mysql; 3,update user set ...

  10. vscode快捷键-for mac

    默认显示当前所有页面: command p ?: 显示可操作方法 >: 打开命令面板, 同comand shift p : : 跳转到对应行数 @: 搜索并跳转到应变量或函数 @: : 同上,分 ...