VC下防止反汇编的办法(1)
最近在看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)的更多相关文章
- VC下Debug和Release区别
整理日: 2015年3月23日 最近写代码过程中,发现 Debug 下运行正常,Release 下就会出现问题,百思不得其解,而Release 下又无法进行调试,于是只能采用printf方式逐步定位到 ...
- VC下加载JPG/GIF/PNG图片的两种方法
转载自:http://blog.sina.com.cn/s/blog_6582aa410100huil.html 仅管VC有提供相应的API和类来操作bmp位图.图标和(增强)元文件,但却不支持jpg ...
- VC 下加载 JPG / JPEG / GIF / PNG 图片最简单的方法
VC MFC 提供的 API LoadBitmap / LoadImage 类 CBitmap 等都只能操作 BMP 位图,图标.对于其他常用的 JPG / JPEG / GIF / PNG 格式,它 ...
- VC下加载多种格式图片的方法总结IPicture, CxImage, CImage(AtlImage), CPictureEx
尽管VC有提供相应的API和类来操作bmp位图.图标和(增强)元文件,但却不支持jpg.gif和png等格式的图片,而这几种格式却是常常要用到的.这里我给大家介绍两种办法来操作这些格式的图片. 1.用 ...
- 【VS开发】VC下加载JPG/GIF/PNG图片的两种方法
1.用API OleLoadPicture来加载JPG.GIF格式的图片(注:不支持PNG格式,另外GIF只能加载第一帧,且不支持透明) OleLoadPicture 函数实际上创建了一个IPictu ...
- 在VC下采用ADO实现BLOB(Binary)数据的存储,读取,修改,删除。
在VC下采用ADO实现BLOB(Binary)数据的存储,读取,修改,删除. 作者:邵盛松 2009-09-05 前言 1关于的BLOB(Binary)数据的存储和读取功能主要参考了MSDN上的一篇& ...
- VC++下封装ADO类以及使用方法
操作系统:windows 7软件环境:visual studio 2008 .Microsoft SQL 2005本次目的:介绍一个已经封装的ADO类,简单说明怎么导入使用 首先声明一下,这个封装的A ...
- 在VC下显示JPEG、GIF格式图像的一种简便方法
在VC下显示JPEG.GIF格式图像的一种简便方法 一. 引言 JPEG图像压缩标准随然是一种有损图像压缩标准,但由于人眼视觉的不敏感,经压缩后的画质基本没有发生变化,很快便以较高的压缩率得到了广泛 ...
- VC++下使用ADO操作数据库
VC++下使用ADO操作数据库主要要用到 _ConnectionPtr,_CommandPtr,_RecordsetPtr三个ADO对象指针,我查找了相关资料,发现网上源码很多,但是都相对凌乱,于是自 ...
随机推荐
- 虚拟主机导入MySQL出现Unknown character set: ‘utf8mb4’
http://www.lmlblog.com/14.html 前几天进行网站搬家,MySQL导入数据的时候,出现以下错误(没有定义的编码集utf8mb4): SQL 查询: ; MySQL 返回:文档 ...
- destoon数据库表解释说明
----------------------------- 公司认证:vcompany 实名认证:vtarde ============================================ ...
- 【编程技巧】applicationContext.xml 里面可配置bean和数据库地址
<bean id="vendorManagerDao" class="com.active.vendor.dao.VendorManagerDaoImpl" ...
- Java XML 序列化和反序列化
Utils 类: import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileWr ...
- 微信小程序实现顶部、底部联动滑动
这个场景一般用于展示数据时,数据过多,每条一行显示不下,表头可以横向滑动,下面要显示的数据部分横向纵向都可以滑动.表头或下面数据部分横向滑动的时候,两部分可以进行联动 具体效果像这样(随便写的丑样式布 ...
- RAC和单节点数据库的区别有哪些?RAC最有用的功能是什么?
区别 (1)RAC有2个以上的实例,单节点只有1个实例 (2)RAC具有实例级别的高可用 (3)实例与实例之间通过内联网络交换数据,单节点不可 (4)RAC每个节点都有自己套SGA.后台进程.redo ...
- TF-卷积函数 tf.nn.conv2d 介绍
转自 http://www.cnblogs.com/welhzh/p/6607581.html 下面是这位博主自己的翻译加上测试心得 tf.nn.conv2d是TensorFlow里面实现卷积的函数, ...
- python_冒泡算法
什么是冒泡算法? -- 像鱼吐泡泡一样,每次都是向上冒出一个水泡 如何逻辑整理? -- 先拿第一个值和剩下的值,一一比较,必能找到最大的或者最小的 -- 比较过程中,第一个值小于剩下的某个值,交换位置 ...
- Web Magic 简介
WebMagic in Action Little book of WebMagic. WebMagic是我业余开发的一款简单灵活的爬虫框架.基于它你可以很容易的编写一个爬虫. 这本小书以WebMag ...
- C#高性能大容量SOCKET并发(八):通讯协议
协议种类 开发Socket程序有两种协议类型,一种是用文本描述的,类似HTTP协议,定义字符集,好处是兼容性和调试方便,缺点是解析文本会损耗一些性能:一种是用Code加结构体,定义字节顺序,好处是性能 ...