感谢这位同学提供的HOOKME!点我进他看雪主页~
我们通过字符串即可知道:
push 0x47E6A8是压入标题
push 0x47E6B5是压入提示信息
既然上面两个push压入了信息的地址
那么我们只需要在push标题之前跳转到我们的代码区
在我们的代码区进行压栈最后跳回push提示信息之后不就好了吗?
在DLL_PROCESS_ATTACH事件(初次映射事件)添加处理函数HOOK
现在我们定义出跳转到我们的函数的跳转命令
因为这是一个长跳转,所以跳转指令需要五个字节
现在问题来了:
后面的地址怎么表示呢?
我们回到OD 找一找其他的跳转指令
观察短跳指令
我们发现从je指令开始(0x4010CC)到跳转的位置(0x4010EA)相差
然而跳转指令后面是1C
1C与1E差2,正好是跳转指令的长度
一个可能有偶然性,我们再找一个跳转
观察长跳指令
我们发现从jnz指令开始(0x4010D3)到跳转的位置(0x40115F)相差
然而跳转指令后面是86
8C与86差6,正好是跳转指令的长度
可以确定:
jmp 某地址
E9 [从跳转指令的字节到欲跳转的地址的相差字节数]
了解了跳转命令之后就好办多了
先创建一个函数用来压栈与跳回:
__declspec(naked)就是用来告诉编译器这个函数代码的汇编代码是我们自己写的,不要自动添加任何汇编指令
现在我们定义修改jmp指令的位置,我们需要覆盖掉0x401014位置的代码
那么偏移为:该命令所在地址 - 该函数所在模块基址
即 0x401014 - 0x400000 = 0x1014
所以修改地址为:
(GetModuleHandle这个函数可以获取本程序某个模块的基地址)
那么跳转指令就应该:
现在我们就把jmp指令构建好了,现在我们写入程序
因为此dll稍后会注入HookMePlease.exe所以可以使用GetCurrentProcess()来写自身内存
这样程序再运行到0x401014时就会跳入我们的Push函数
现在编写Push函数代码
我们现在修改的跳转位置直接覆盖掉了push 0x47E6A8(压入标题)
所以我们第一条push指令需要压入标题地址
先定义一个字符串用来储存标题(必须在Push函数外定义变量)
然后创建一个遍历用于储存标题地址(楼主本来想直接push [TitleText],但是并不能这样,如果哪位大佬知道如何直接push而不用创建变量麻烦告知一下谢谢:) )
然后进行压栈
然后压入跳过的值
提示信息和标题一样
最后我们跳回原程序的call
在我们的函数里
内容已经压入了,那么我们就跳到压提示信息的下一行即可
计算本行代码偏移地址即可得出
最后跳回该位置
现在HOOKdll就写好了
编译注入试一试(楼主采用ProcessHack自带的dll注入)
现在看一看OD里代码变成了什么样
看!我们修改的地方已被OD标红
检查修改位置没有问题
回车红色指令看看
和我们写的真的是一模一样呢 (为什么标识符名称都有呢...)
大家在第一次写这种HOOK时不一定会完全写对 (我第一次写的乱七八糟)
所以调试也是非常有必要的
(楼主在写这篇文章的时候就出了错...所以调试很有必要)
在段头下断点,回到窗口按下按钮
使用单步步过调试(F8)
现在我们向下压
栈中已经出现了字符串~
现在删除所有断点试一试有没有修改
~完美
0.感谢这位同学给我提供了灵感和HOOKME~
BYTE JmpCode[
5
];
JmpCode[
0
]
=
0xE9
;
/
/
E9就是汇编jmp命令
BYTE JmpCode[
5
];
JmpCode[
0
]
=
0xE9
;
/
/
E9就是汇编jmp命令
void __declspec(naked) Push() {
__asm {
}
}
void __declspec(naked) Push() {
__asm {
}
}
DWORD Address
=
(DWORD)GetModuleHandle(
"HookMePlease.exe"
)
+
0x1014
;
DWORD Address
=
(DWORD)GetModuleHandle(
"HookMePlease.exe"
)
+
0x1014
;
DWORD cha
=
(DWORD)&Push
-
Address
-
5
;
/
/
计算Push函数到修改地址的长度
*
(DWORD
*
)&JmpCode[
1
]
=
cha;
/
/
将差值写入跳转指令的后面四个字节
DWORD cha
=
(DWORD)&Push
-
Address
-
5
;
/
/
计算Push函数到修改地址的长度
*
(DWORD
*
)&JmpCode[
1
]
=
cha;
/
/
将差值写入跳转指令的后面四个字节
WriteProcessMemory(GetCurrentProcess(), (LPVOID)Address, &JmpCode, sizeof(JmpCode), NULL);
WriteProcessMemory(GetCurrentProcess(), (LPVOID)Address, &JmpCode, sizeof(JmpCode), NULL);
char TitleText[]
=
"OK~"
;
char TitleText[]
=
"OK~"
;
DWORD TitleTextAddress
=
(DWORD)&TitleText;
DWORD TitleTextAddress
=
(DWORD)&TitleText;
void __declspec(naked) Push() {
__asm {
push TitleTextAddress
}
}
void __declspec(naked) Push() {
__asm {
push TitleTextAddress
}
}
void __declspec(naked) Push() {
__asm {
push TitleTextAddress
push
80000301h
push
0h
push
40h
push
80000004h
push
0h
}
}
void __declspec(naked) Push() {
__asm {
push TitleTextAddress
push
80000301h
push
0h
push
40h
push
80000004h
push
0h
}
}
char Text[]
=
"Yes,I can~ ,I have changed your information!"
;
char Text[]
=
"Yes,I can~ ,I have changed your information!"
;
DWORD TextAddress
=
(DWORD)&Text;
DWORD TextAddress
=
(DWORD)&Text;
void __declspec(naked) Push() {
__asm {
push TitleTextAddress
push
80000301h
push
0h
push
40h
push
80000004h
push
0h
push TextAddress
}
}
void __declspec(naked) Push() {
__asm {
push TitleTextAddress
push
80000301h
push
0h
push
40h
push
80000004h
push
0h
push TextAddress
}
}
DWORD RetAddress
=
(DWORD)GetModuleHandle(
"HookMePlease.exe"
)
+
0x1031
;
DWORD RetAddress
=
(DWORD)GetModuleHandle(
"HookMePlease.exe"
)
+
0x1031
;
void __declspec(naked) Push() {
__asm {
push TitleTextAddress
push
80000301h
push
0h
push
40h
push
80000004h
push
0h
push TextAddress
jmp RetAddress
}
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2022-1-25 15:58
被Axinger编辑
,原因: 还有图片没有成功上传