PP N开原理简单剖析哦, 只逆了小部分,上班再弄.
(功能的找法定位在搜索和遍历.另外关于车辆信息和人物信息的指针结构已经移入堆栈.目前不可修改,可以通过其它手段获得 但不固定)
屏蔽邀请部分:
*[结构地址+0x14] == 某变量地址
*[结构地址+0x14] - 0xc ==某前面的变量地址
++*[*[结构地址+ 0x14] - 4]- int __stdcall sub_10001030(int argContext)
- {
- int result; // eax@1
- result = HeapStart;
- if ( HeapStart )
- {
- result = phHeap;
- if ( phHeap )
- {
- if ( argContext )
- {
- **(argContext + 0x14) = 49;
- *(*(argContext + 0x14) - 0xC) = 1;
- result = isEnable;
- if ( !isEnable )
- {
- ++*(*(argContext + 0x14) - 4); // 某二级结构变量值自加
- *HeapStart = HeapAlloc(*phHeap, 0, 4u);
- *(HeapStart + 4) = *HeapStart + 4; // 保存自身地址
- *(HeapStart + 8) = *(HeapStart + 4);
- result = *HeapStart;
- **HeapStart = *(argContext + 0x14);
- isEnable = 1;
- }
- }
- }
- 最后一段看起来没什么用,有点像AheadLib对Tls的处理..
dword_10008E64 = *(*(Section1_Vaddr + 0xB) + Section1_Vaddr + 0x17);
dword_10008E64 += *(*(Section1_Vaddr + 18) + Section1_Vaddr + 33);
这两句一直看不懂, 因为Section1_Vaddr已经指向了themida加壳后的第一个节区,不知道0x17 33两处代表什么意思.argContext在Hook点自行获取, -- > ecx (为何要用这样的方法呢,因为ECX的指针不固定,第二点可以不用更新.那么为什么人物指针等不用这个方法呢?因为人物指针所经过的call们都是全局共享的.)
LABEL_55:
if ( dword_10008E5C )
{
BeginOfData = (KartRider(00400000) + baseOfData);
EndOfdata = (KartRider(00400000) + baseOfData + SizeOfInitializedData - 16);
if ( (KartRider(00400000) + baseOfData) < EndOfdata )
{
while ( 1 )
{
count = 4;
pKeyStr = "PqInviteRider"; // 游戏内的DbgPrint输出字符串当#define DEBUG_打开时调用
TempAddress = BeginOfData;
IfFound = 1;
do
{
if ( !count )
break;
IfFound = *TempAddress == *pKeyStr;
TempAddress += 4;
pKeyStr += 4;
--count;
}
while ( IfFound );
if ( IfFound )
break;
++BeginOfData;
if ( BeginOfData >= EndOfdata )
goto LABEL_65;
}
originalCallAddr = *(BeginOfData + 0x20);
*(BeginOfData + 0x20) = FilterStubFunction;
}
}
}
}
FilterStubFunction proc near
pop retAddress
mov argContext, ecx
lea eax, newRet__
push eax
mov eax, originalCallAddr
jmp eax
:
pop dword [OriginalRetAddress]
mov argContext,ecx 保存参数指针
lea eax, newRet__ 压入新的返回地址
push eax
mov eax,originalCallAddr
jmp eax --使用原参数调用原始的CALL,一个原本只执行一次的初始化call
返回到这里:
newRet__:
push argContext 压入之前的参数(已被ORGCALL初始化)
call sub_10001030 处理已被初始化的结构。
jmp [ OriginalRetAddress ]
[ 此帖被sprees在2013-11-29 17:07重新编辑 ]