首页
社区
课程
招聘
[已解决]VC2008写内存一夜未成功
发表于: 2009-10-14 09:33 6300

[已解决]VC2008写内存一夜未成功

2009-10-14 09:33
6300
想用VC2008写个HOOK API的DLL,先拿GetClassName做实验

static BYTE OldCode[12];//原GetClassName头代码
static BYTE NewCode[12];//新GetClassName头代码

PVOID OldFunEntry;//GetClassName地址,在我的机器上是77d2f420

void Change()//修改GetClassName头
{
WriteProcessMemory(hHandle, OldFunEntry, NewCode, 12, &RetSize);//替换GetClassName头成功
}

void Restore()//还原GetClassName头
{
VirtualProtect(OldFunEntry,12,PAGE_READWRITE,&dwold);
WriteProcessMemory(hHandle, OldFunEntry, OldCode, 12, &RetSize);//。。。。。。
VirtualProtect(OldFunEntry,12,dwold,&dwold2);
}

原版GetClassName:
77D2F420 >  [COLOR="Green"]6A[/COLOR] [COLOR="Blue"]14[/COLOR]           push    14
77D2F422    [COLOR="Blue"]68 A0F4D277[/COLOR]     push    77D2F4A0
77D2F427    [COLOR="Blue"]E8 9491FEFF[/COLOR]     call    77D185C0
77D2F42C    8B4D 08         mov     ecx, dword ptr [ebp+8]
77D2F42F    E8 9C90FEFF     call    77D184D0
77D2F434    85C0            test    eax, eax


DLL注入后先执行Change,执行成功,修改后函数头变为
77D2F420 >  [COLOR="Red"]8B[/COLOR]FF            mov     edi, edi


再执行Restore,执行后GetClassName头变为:
77D2F420 >  [COLOR="Red"]8B[/COLOR][COLOR="Blue"]1468[/COLOR]          mov     edx, dword ptr [eax+ebp*2]
77D2F423    [COLOR="Blue"]A0 F4D277E8[/COLOR]     mov     al, byte ptr [E877D2F4]
77D2F428    [COLOR="Blue"]94[/COLOR]              xchg    eax, esp
77D2F429    [COLOR="Blue"]91[/COLOR]              xchg    eax, ecx
77D2F42A    [COLOR="Blue"]FE[/COLOR]              ???                                      ; 未知命令
77D2F42B    [COLOR="Blue"]FF[/COLOR]8B 4D08E89C   dec     dword ptr [ebx+9CE8084D]
77D2F431    90              nop
77D2F432    FE              ???                                      ; 未知命令
77D2F433    FF85 C0745B83   inc     dword ptr [ebp+835B74C0]


用OD看到的Restore内代码
100011E7    8B06            mov     eax, dword ptr [esi]             ; user32.GetClassNameA
100011E9    8D5424 08       lea     edx, dword ptr [esp+8]
100011ED    52              push    edx
100011EE    6A 0C           push    0C
100011F0    68 10300010     push    10003010      //OldCode
100011F5    50              push    eax                              ; user32.GetClassNameA
100011F6    57              push    edi
100011F7    FF15 14200010   call    dword ptr [<&KERNEL32.WriteProce>; kernel32.WriteProcessMemory

/////OldCode:
10003010  [COLOR="Green"]6A[/COLOR] [COLOR="Blue"]14 68 A0 F4 D2 77 E8 94 91 FE FF[/COLOR] 8B FF 55 8B  jh狋襴钄扊?U


怎么12位的OldCode后11位都写入成功,只有第1位失败了呢?
之前Change时没有用VirtualProtect也写入成功了啊....

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

收藏
免费 0
支持
分享
最新回复 (12)
雪    币: 290
活跃值: (20)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
看不懂楼主的意思和代码

而且看你给出的反汇编代码,只需要备份七个字节就可以了
可以改成90 90 e9 xx xx xx xx这样不好些??
2009-10-14 11:12
0
雪    币: 376
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
激动了半天,没把问题说明白...

我想HOOK GetClassName,GetClassName在我的机器上地址是0x77d2f420
系统默认状态0x77D2F420的内容是"6A14"--->"push    14"
我的HOOK修改函数Change函数把0x77D2F420修改成了"8BFF"--->"mov     edi, edi"

现在想把0x77D2F420的内容还原成系统的"6A14"[此时0x77D2F420的内容是"8BFF"]
但是怎么都改不回来
用WriteProcessMemory无法修改0x77D2F420的内容
2009-10-14 12:25
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
LZ牛人贴看太多了。  
提的很专业  就是问题不专业啊。  

自己单步F10下  看问题出在哪不就完了。。。
2009-10-14 14:18
0
雪    币: 290
活跃值: (20)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
使用SHELL CODE实现的HOOK?不然为什么需要用WriteProcessMemory?memcpy以及直接*(WORD *)地址=xxx不行吗??

还有什么修复内容永远不对,你可以在恢复内存那个地方下个断点,首先察看目标地址对了吗?然后值对吗?
2009-10-14 14:34
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
WriteProcessMemory返回值是什么?
2009-10-14 14:56
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
7
可能你用了某些OD插件,也在hook此函数.
2009-10-14 15:21
0
雪    币: 376
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
我原本也以为写个内存一下就搞定的。。没想到搞了这么就都没完成。。。结果只好把这么不专业的问题拿出来了。。。

之前用过CopyMemory来覆盖"GetClassName"函数头,失败了

OldFunEntry=0x77D2F420;
WriteProcessMemory(hHandle, OldFunEntry, OldCode, 12, &RetSize)
这段代码就是用于恢复GetClassName的WriteProcessMemory,OD里查看调用时的状态:
100011E7    8B06            mov     eax, dword ptr [esi]             ; user32.GetClassNameA
100011E9    8D5424 08       lea     edx, dword ptr [esp+8]
100011ED    52              push    edx
100011EE    6A 0C           push    0C
100011F0    68 10300010     push    10003010             //OldCode内容在下面的
100011F5    50              push    eax                              ; user32.GetClassNameA //eax=0x77D2F420
100011F6    57              push    edi
100011F7    FF15 14200010   call    dword ptr [<&KERNEL32.WriteProce>; kernel32.WriteProcessMemory

/////用OD看到的OldCode内容:
10003010  6A 14 68 A0 F4 D2 77 E8 94 91 FE FF 8B FF 55 8B  jh狋襴钄扊?U

上面的WriteProcessMemory执行后,"GetClassNameA"函数头变成了
77D2F420 >  8B1468          mov     edx, dword ptr [eax+ebp*2]

WriteProcessMemory执行结果就是:
WriteProcessMemory将OldCode[0]=0x6A写入0x77D2F420->失败
WriteProcessMemory将OldCode[1]=0x14写入0x77D2F421->成功
WriteProcessMemory将OldCode[2]=0x68写入0x77D2F422->成功
WriteProcessMemory将OldCode[3...11]写入0x77D2F423...->成功

WriteProcessMemory返回值记不清了...现在也没有在那台机器上坐,等看到再了发上来

晚上再用无插件的OD试试
2009-10-14 16:51
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
有可能,另一个可能是那儿有个int3断点,而原来的值被Debugger保存起来的
显示的时候Debugger会欺骗你,让你认为那儿的值没变,本意是隐藏了断点这种细节,结果也把楼主的修改隐藏了。
可以在没有Debugger的情况下,写完,再读一下,然后打印出来看看
2009-10-14 17:51
0
雪    币: 367
活跃值: (20)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
10
这是最可靠的,写完再读一次校验.

修改内存最好是不要100%相信debugger的显示.因为 debugger可能hook我们正在操作的函数,也可能是debugger的int3断点的处理,甚至没有更新内存视图(VC6的Debugger).
2009-10-14 20:08
0
雪    币: 29
活跃值: (1489)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
用指针做,还有PAGE_EXECUTE_READWRITE
2009-10-14 22:29
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
改个内存地址的值 有这么复杂吗.....  
0x77D2F420 应该是在NTDLL里
改下内存属性 就可以读写了哦 肯定是你自己哪里弄错了
2009-10-15 01:25
0
雪    币: 376
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
好像是因为在0x77D2F420用OD F2下了断点,所以才一直没有看(改)到正常的结果...

真是一个相当抱歉的问题...让大家费心了
2009-10-15 03:30
0
游客
登录 | 注册 方可回帖
返回
//