最近在看IDA的书,讲汇编语言的部分提到了一种防止递归向下汇编器逆向程序的方法

这里esp指向栈顶,也就是调用方最后入栈的返回地址。然而实际在VC2017里用内联汇编这么做是不行的,原因可以看看VC生成的汇编 代码:

 int __stdcall func1(int param)
{
00AC10A0 push ebp
00AC10A1 mov ebp,esp
00AC10A3 sub esp,
int local = param;
00AC10A6 mov eax,dword ptr [param]
00AC10A9 mov dword ptr [local],eax
int local2 = + param;
00AC10AC mov ecx,dword ptr [param]
00AC10AF add ecx,
00AC10B2 mov dword ptr [local2],ecx
_asm{
add dword ptr[ebp+],
00AC10B5 add dword ptr [ebp+],0Dh
}
return param*;
00AC10B9 mov eax,dword ptr [param]
00AC10BC shl eax,
}
00AC10BE mov esp,ebp
00AC10C0 pop ebp
}

可以看到VC生成的汇编代码中添加了一些前缀后缀:

前缀用来保存调用前堆栈顶ebp,还有设置新的堆栈顶位置到ebp。如果有局部变量,还要减少esp位置(相当于入栈几个未知数据)以留出局部变量的位置。注意函数堆栈是从内存大编号向小编号堆叠的,越大的地址编号越靠下,就像一个金字塔,下大上小。

后缀用来清理堆栈(mov esp,ebp),并且从堆栈中恢复此次调用之前的ebp(pop ebp)。不难发现在被调用的函数体内修改函数返回地址的话,就需略过ebp的位置。因此内嵌汇编的那一句需要用ebp+4来得到返回地址指针。后面地址+13是略过的调用方的一个printf方法调用,要跳过多少代码可以在反汇编窗口自行查看地址计算一下。

下面是调用方的代码:

int main()
{
00AC1002 in al,dx
00AC1003 sub esp,1Ch
00AC1006 mov eax,dword ptr [__security_cookie (0AC3000h)]
00AC100B xor eax,ebp
00AC100D mov dword ptr [ebp-],eax
int d = ;
00AC1010 mov dword ptr [d],0Ah
func1();
00AC1017 push 0Ah
00AC1019 call func1 (0AC10A0h)
printf("loc1\n");
00AC101E push 0AC20F8h
00AC1023 call printf (0AC1140h)
00AC1028 add esp,
printf("loc2\n");
00AC102B push 0AC2100h
00AC1030 call printf (0AC1140h)
00AC1035 add esp,
int a[] = {,,,,};
00AC1038 mov dword ptr [a],
00AC103F mov dword ptr [ebp-14h],
00AC1046 mov dword ptr [ebp-10h],
00AC104D mov dword ptr [ebp-0Ch],
00AC1054 mov dword ptr [ebp-],
printf("%d\b",func2(a));
00AC105B lea eax,[a]
00AC105E push eax
00AC105F call func2 (0AC10D0h)
00AC1064 add esp,
00AC1067 push eax
00AC1068 push 0AC2108h
00AC106D call printf (0AC1140h)
00AC1072 add esp,
printf("writing code...\n");
00AC1075 push 0AC210Ch
00AC107A call printf (0AC1140h)
00AC107F add esp,
func3();
00AC1082 call __vcrt_va_start_verify_argument_type<char const * const> (0AC10F0h)
getchar();
00AC1087 call dword ptr [__imp__getchar (0AC20A8h)]
return ;
00AC108D xor eax,eax
}

还有要注意的是这里为了防止代码优化,要关闭vc的编译优化选项。用以上这种方法可以配合一些跳转让反汇编的工具不能正确预测哪部分是代码区,从而达到隐藏一部分代码的目的。

以上是STDCALL调用约定的例子,cdecl和其他约定的以后再尝试整理。

VC下防止反汇编的办法(1)的更多相关文章

  1. VC下Debug和Release区别

    整理日: 2015年3月23日 最近写代码过程中,发现 Debug 下运行正常,Release 下就会出现问题,百思不得其解,而Release 下又无法进行调试,于是只能采用printf方式逐步定位到 ...

  2. VC下加载JPG/GIF/PNG图片的两种方法

    转载自:http://blog.sina.com.cn/s/blog_6582aa410100huil.html 仅管VC有提供相应的API和类来操作bmp位图.图标和(增强)元文件,但却不支持jpg ...

  3. VC 下加载 JPG / JPEG / GIF / PNG 图片最简单的方法

    VC MFC 提供的 API LoadBitmap / LoadImage 类 CBitmap 等都只能操作 BMP 位图,图标.对于其他常用的 JPG / JPEG / GIF / PNG 格式,它 ...

  4. VC下加载多种格式图片的方法总结IPicture, CxImage, CImage(AtlImage), CPictureEx

    尽管VC有提供相应的API和类来操作bmp位图.图标和(增强)元文件,但却不支持jpg.gif和png等格式的图片,而这几种格式却是常常要用到的.这里我给大家介绍两种办法来操作这些格式的图片. 1.用 ...

  5. 【VS开发】VC下加载JPG/GIF/PNG图片的两种方法

    1.用API OleLoadPicture来加载JPG.GIF格式的图片(注:不支持PNG格式,另外GIF只能加载第一帧,且不支持透明) OleLoadPicture 函数实际上创建了一个IPictu ...

  6. 在VC下采用ADO实现BLOB(Binary)数据的存储,读取,修改,删除。

    在VC下采用ADO实现BLOB(Binary)数据的存储,读取,修改,删除. 作者:邵盛松 2009-09-05 前言 1关于的BLOB(Binary)数据的存储和读取功能主要参考了MSDN上的一篇& ...

  7. VC++下封装ADO类以及使用方法

    操作系统:windows 7软件环境:visual studio 2008 .Microsoft SQL 2005本次目的:介绍一个已经封装的ADO类,简单说明怎么导入使用 首先声明一下,这个封装的A ...

  8. 在VC下显示JPEG、GIF格式图像的一种简便方法

    在VC下显示JPEG.GIF格式图像的一种简便方法 一. 引言  JPEG图像压缩标准随然是一种有损图像压缩标准,但由于人眼视觉的不敏感,经压缩后的画质基本没有发生变化,很快便以较高的压缩率得到了广泛 ...

  9. VC++下使用ADO操作数据库

    VC++下使用ADO操作数据库主要要用到 _ConnectionPtr,_CommandPtr,_RecordsetPtr三个ADO对象指针,我查找了相关资料,发现网上源码很多,但是都相对凌乱,于是自 ...

随机推荐

  1. JavaSE笔记-泛型

    定义带泛型的类 public class Cat<T> { //可以用T定义实例变量 private T name; //可以用T定义形参 //构造器没有<> public C ...

  2. 设置vs环境

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  3. FORTH 安装使用

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  4. Web Magic 简介

    WebMagic in Action Little book of WebMagic. WebMagic是我业余开发的一款简单灵活的爬虫框架.基于它你可以很容易的编写一个爬虫. 这本小书以WebMag ...

  5. Servlet--继承HttpServlet写自己的Servlet

    前面2篇关注的都是Servlet接口,在实际编码中一般不直接实现这个接口,而是继承HttpServlet类.因为j2e的包里面写好了GenericServlet和HttpServlet类来让我们简化编 ...

  6. SCOPE_IDENTITY()

    @@IDENTYITY,SCOPE_IDENTITY的主要区别:在有触发器中而且触发器的内容里面含有插入标识符的操作的时候,@@IDENTITY则返回的是触发器里面新插入标识符的值而SCOPE_IDE ...

  7. 使用jQuery的ajax调用action的例子

    直接使用ajax请求会比较繁琐,但是jQuery为我们提供了简单使用ajax的方法. 下面是一个在jQuery easyUI中,利用ajax请求,使下拉菜单关联文本框的例子.其中ajax请求就是8-1 ...

  8. jQuery Validate验证框架与 jQuery ajaxSubmit的联合使用

    jQuery Validate验证框架自定义验证 第一步导入导入js库 <script src="<%=basePath%>static/js/jquery.js" ...

  9. 布衣之路(一):VMware虚拟机+CentOS系统安装

    前言:布衣博主乃苦逼的Java程序猿一枚,虽然工作中不会涉及系统运维,但是开发的项目总还是要部署到服务器做一些负载均衡.系统兼容性测试.系统集成等等骚操作,而这些测试性的操作不可能直接SSH远程运维的 ...

  10. IE各个版本的差异性

    1.IE6a.不支持png半透明图片,只能用filter实现b.不支持css的max-width.max-height.min-width.min-height其他不用说,一团糟,不过项目中还是得去兼 ...