我遇到了一个我无法解决的问题所以我不得不求助于社区来帮助我。问题与PPC功能挂钩有关。
我挂钩的地方就是这个。
.text:8220D810 mflr r12
.text:8220D814 bl __savegprlr_20
.text:8220D818 stfd f31, var_70(r1)
.text:8220D81C stwu r1, -0x100(r1)
.text:8220D820 lis r11, off_82A9CCC0@ha // => This is where i am hooking the function
.text:8220D824 lis r22, dword_82BBAE68@ha // These 4 instructions are overwritt
.text:8220D828 lis r10, 8 # 0x87700 //Patched
.text:8220D82C mr r26, r3 //Patched
.text:8220D830 li r20, 0
.text:8220D834 lwz r9, off_82A9CCC0@l(r11)
.text:8220D838 ori r23, r10, 0x7700 # 0x87700
.text:8220D83C lwz r11, dword_82BBAE68@l(r22)
.text:8220D840 cmplwi cr6, r11, 0
.text:8220D844 stw r9, 0x100+var_7C(r1)
.text:8220D848 bne cr6, loc_8220D854
.text:8220D84C mr r30, r20
.text:8220D850 b loc_8220D85C
这里跳转到我下面提到的代码洞穴。已修补的指令在PredictPlayerHook函数中正确写入,不是问题。
这里的问题是如果我在钩子中调用一个函数,例如这里我称之为“GetCurrentCmdNumber(0);”它会导致游戏崩溃。现在没有调用任何函数,游戏不会崩溃,代码洞穴也没有任何问题。但如果我尝试调用代码洞内的任何函数(PredictPlayerHook),它就会崩溃。我无法调试它,所以我不知道它崩溃的地方。
void __declspec(naked) PredictPlayerHook(){
DWORD R11,Return,cmdNumber;
__asm lis r11, 0x82AA //patched instructions
__asm lis r22, 0x82BC //patched instructions
__asm lis r10, 0x8 //patched instructions
__asm mr r26, r3 //patched instructions
__asm mflr r0 ; //mflr grabs the link register, and stores it into the first operand. r0 is now the link register
__asm stw r0, -0x14(r1) ; //Save the link register inside the stack frame
__asm stwu r1, -0x90(r1) ;// This is pushing the stack (hence push)
// cmdNumber = GetCurrentCmdNumber(0);
__asm addi r1, r1, 0x90 ;//popping the stack frame
__asm lwz r0,-0x14(r1) ; //Reading the link register from the sack
__asm mtlr r0
__asm stw r11,R11
//Return = 0x82200230;
__asm lis r11,0x8220 //Return Address is correct. The difference is in IDA segment, it is +0xD600 ahead of the original address.
__asm ori r11,r11,0x0230
__asm mtctr r11
__asm lwz r11,R11
__asm bctr
}
这是函数本身及其正确性。我可以在游戏中的其他位置使用它,因此它没有任何问题。
typedef int (__cdecl* CL_GetCurrentCmdNumber)(int localClientNum);
CL_GetCurrentCmdNumber GetCurrentCmdNumber = (CL_GetCurrentCmdNumber)0x82261F90;