能力值:
(RANK:260 )
|
-
-
2 楼
不不懂DELPHI的内嵌汇编,单从汇编语法上,你的代码存在以下问题:
如果没有寄存器操作数而使用立即数来写入内存单元,需要指出内存操作数的位宽度
mov dword ptr [ecx+00000066],1
因为eax是32位寄存器,用eax时已经包含了位宽信息,所以不用写dword ptr ,而用立即数时不包含位宽信息,所以必须显式地写出来。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
书大哥,你能回我贴真是荣幸。我是这样的。这段代码我是在玩仙剑4里面。找到的一个地址。
用的是CE。然后找到谁在读这个地址。 出来了这一段。然后我在CE里面直接修改了。可以实现我想要的效果。让ecx+66 的结果等于我想给的值。
我只是想问。如果像这种代码段。如果通过程序来直接修改他。可以实现吗?需不需要找什么基址之类的?
|
能力值:
(RANK:260 )
|
-
-
4 楼
如果你想直接修改程序代码,这两条指令的长度不同。
“mov [ecx+0x66],eax” 是3个字节,而“mov dword ptr [ecx+0x66],1” 是8个字节。所以,必须通过jmp的方式来实现。
而且你在自己的程序中asm的代码,并不对其它进程产生任何影响啊!
你要实现自己控制写入的值,可以通过修改CONTEXT中的EAX来间接地实现。
或者,通过直接将机器码写入目标进程的代码段中来实现。
你用asm写的代码是在自己的进程中,不是在目标进程中。
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
我是用的看雪大哥在加密解密里面用的DLL劫持方法。让仙剑程序呼出我的DLL。。如果是这样。是不是可以当作是它的程序?
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
还有。如果您不忙的话。能不能写一段示例给我看下。不论是什么语言都行。我只是想学习一下。谢谢了。
|
能力值:
(RANK:410 )
|
-
-
7 楼
// CE具有将汇编指令转换成机器码的能力,所以你可以在CE里直接使用汇编指令修改程序。而Delphi可不带有这个功能。像你这样写只是你的Delphi程序有这段代码存在,和你要修改的程序完全没有关系联系。要修改其他程序,要像下面的代码那样写才行(注:下面的代码机器码指令长度比原来的指令长度要长,肯定会破坏你的游戏后面的指令完整性,如果你修改时不注意这个,估计这样修改会Down掉你的游戏,而如果你在CE里这样修改不会出错,应该是CE里用NOP处理了被破坏的指令,这样做结果程序是不会Down掉,但执行指令也肯定已经缺少一两条指令了。)
。
var lpAsmByte:Array[1..7] of Byte = ($C7,$41,$66,01,00,00,00); // 全局变量,是mov DWORD ptr [ecx+66],1的机器码
var dwProcessID,NumberOfBytesWritten:DWORD;
hProcess:THANDLE;
begin
hWindow := FindWindow('游戏窗口类名','游戏窗口标题名'); // 根据游戏窗口类名或游戏窗口标题名找到要修改的游戏窗口句柄。
GetWindowThreadProcessId(hWindow,dwProcessID); // 取得游戏窗口进程ID
hProcess := OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessID); // 打开游戏进程,以便下面进行修改游戏。
WriteProcessMemory(hProcess,Pointer($510bed),@lpAsmByte,sizeof(lpAsmByte),NumberOfBytesWritten); // 在510bed处写入mov dword ptr [ecx+66],1指令。
end;
|
能力值:
(RANK:260 )
|
-
-
8 楼
如果已经进入了目标进程的地址空间,事情就比较简单了。
以下代码没有经过测试,仅供参考,注意红字部分需要根据具体程序进行修改:
// 这是要修改的地址
const void* patchAddress = 0x510bed;
// 这是下一条指令的地址,我们的代码执行完成后要回到这里
const void* nextInstructionAddress = [COLOR="Red"]0xXXXXXXXX[/COLOR];
// 这是自已的代码
__declspec(naked) void MyHook(void)
{
__asm
{
// [COLOR="Red"]这里要先补上被JMP指令破坏的指令[/COLOR]
mov dword ptr [ecx+0x66], 1
push nextInstructionAddress
retn
}
}
// 执行这个函数来修改代码
void InstallPacth(void)
{
*(BYTE*)(patchAddress) = 0xE9; // opcode of JMP
*(DWORD*)(patchAddress+1) = (DWORD) ((void*)MyHook - (patchAddress + 5)); // offset of JMP
}
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
谢谢小虾大哥和书大哥,受益颇多。非常感谢。
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
有必要这么麻烦吗?
mov [ecx+66],eax
这么一句,要把EAX给定一个自定义的值..很多方法..也可以直接给内存敷值...
比如当时ecx = 00400000..
那就可以这样 00400000+66 = 00400066
可以直接把你要的数值写进00400066下就实现了,和上面这段代码没区别啊.
他就是一个敷值而已..
或许只有当运行这个函数时,才可以给这个内存敷值才会有效果,那你可以把这段汇编改一下,
改成CALL 你的函数指针,当程序运行到这里的时候去调你的一个函数,然后你可以随便给一个值写进那内存就行了...
|
|
|