首页
社区
课程
招聘
PE文件的section载入内存后,不能写入数据
发表于: 2010-5-11 14:23 4398

PE文件的section载入内存后,不能写入数据

2010-5-11 14:23
4398
现在我的程序,把一部分代码用宏
#prama code_seg(push,r1,".secure")
#prama code_seg(pop,r1)
编译到了.secure的节里
然后加密了.secure的节

程序在加载的时候,
会自己解密
方法是寻找.secure的节,读出数据,解密,再写回.secure的节

现在我遇到的问题是在最后
要把数据写回.secure的节的时候,内存拒绝访问"Access violation writting location 0x00411000"
0x00411000是.secure的节在内存中的地址


使用PE工具察看,.secure的节地属性为0xE0000020
查看MSDN,0xE0000020=0x00000020|0x20000000|0x40000000|0x80000000
0x00000020--the section contain executable code
0x20000000--the section can be executed as code
0x40000000--the section can be read
0x80000000--the section can be written to

请高手指点,谢谢先!

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 249
活跃值: (25)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
1.#pragma comment(linker, "/SECTION:.secure,ERW")
2.写入内存的时候用VirtualProtect改变内存属性
以上两种应该都可以
2010-5-11 14:28
0
雪    币: 178
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不错,不过后来发现程序不对不是因为这个原因,是别的地方出错了,我把问题复杂化了
2010-5-12 13:57
0
雪    币: 2
活跃值: (56)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
siz
4
我构造了这样一个程序:
int a;
int main(int argc, char* argv[])
{
static int b;
_asm int 3;
a=0;
b=0;
return 0;
}

用OllyDbg调用这个程序,中断在int3的地方,接下来两句a=0,b=0的反汇编代码如下:
00401028  |.  CC                         int3
00401029  |.  C705 4C7C4200 00000000     mov dword ptr ds:[427C4C], 0
00401033  |.  C705 487C4200 00000000     mov dword ptr ds:[427C48], 0

PEiD里查看,.data节VOffset=24000,VSize=5610,于是27C4C(全局变量a)和27C48(静态变量b)正好在这个节中。

然后是Stack和heap的定位。。。这个我想了好久没什么头绪。。。但是dbg了几个程序,程序开始时ESP的值都是0x0012FFC4...这个。。。不知什么原因。。。。留待研究。。但是也基本可以定位局部变量的位置了,就是小于这个值的空间。。

然后就是堆。。。。这个是最头疼的东西了。。。。记得前几天测试malloc()的时候,也对得到地址的规律莫名了很久。。。。后来单步的时候,碰到了HeapAlloc(),网上搜了一下,可能这两篇文章能有些帮助(后一篇是Linux下的,但是可作为参考):
383K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3u0D9L8$3N6Q4x3X3g2U0M7$3c8F1i4K6u0W2L8X3g2@1i4K6u0r3P5X3g2J5L8K6t1H3y4o6k6Q4x3V1k6S2M7X3y4Z5K9i4k6W2i4K6u0r3x3U0l9H3y4g2)9J5c8U0p5J5i4K6u0r3x3U0y4Q4x3V1j5#2y4e0V1%4y4o6u0Q4x3X3g2S2M7%4m8^5
d56K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3u0D9L8$3N6Q4x3X3g2U0M7$3c8F1i4K6u0W2L8X3g2@1i4K6u0r3k6s2u0A6P5Y4A6@1P5X3!0#2i4K6u0r3j5i4u0U0K9r3W2$3k6g2)9J5c8U0t1H3x3o6N6Q4x3V1j5H3y4W2)9J5c8U0p5I4i4K6u0r3x3e0j5@1z5o6x3J5z5q4)9J5k6h3q4K6M7s2R3`.

这样,大体上可以定位各种各样的数据的存放位置了。然后在这个范围内搜索应该比直接搜索0x00010000~0x7ffeffff快一些。

然后,想到金山游侠有个功能是“暂停当前游戏并切换到普通模式下修改”(或许是其它描述。。记不清楚了。)。。让我一下子想到了SEH(Structured Exception Handling ,windows异常处理机制)。。。也许。。或许。。。金山游侠也是像大多调试器一样,在目标代码中插入int3来断下程序运行以获取各寄存器状态?

然后,你所要修改的游戏数据不是固定地址。。于是再考虑这各种变量类型。。
位于Section中的数据,因为是写入PE文件中的,所以每次加载后,VA不会变化。
而位于栈中的数据,因为执行部分已经写入.text节,所以如果每次执行的时候,ESP确定0x0012FFC4不变的话,那么栈中的数据位置应该也不会变化。。。
那么最有可能的就是数据位于堆中了。。。但是。。我构造了一个小程序,只有两句代码:
int * a = (int *)malloc(1);
printf("%d",a);
多次执行,却得到了相同的结果。。。。。。
2010-5-14 02:55
0
游客
登录 | 注册 方可回帖
返回