对xIkUg的hook lib for delphi研究了一番,尤其是里面的GetOpCodeSize是好东西
,但不太会用delphi,因此转成 VC代码 共享出来。
转好后发现GetOpCodeSize()有点小BUG,草草修正后发上来
先贴代码,然后再说明
{
Name: API Hook Lib for C
Version: 0.2
Author: coded by xIkUg/RCT/CCG modified by 海风月影[NE365]
HomePage: http://www.wintoolspro.com, http://debugman.wintoolspro.com
CreateDate: 2006-12-03
ModifiedDate:2007-3-21
}
#include <windows.h>
#include <stdio.h>
//#pragma comment(linker, "/subsystem:windows /entry:main")
#pragma comment(linker, "/SECTION:.text,REW" ) //设PE节:.text,可读可执行
#pragma comment(linker, "/MERGE:.data=.text") //合并到.text
#pragma comment(linker, "/MERGE:.rdata=.text")//合并到.text
//#pragma comment(linker,"/ALIGN:0x200")
static unsigned long MaskTable[518]={
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00008000, 0x00008000, 0x00000000, 0x00000000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00008000, 0x00008000, 0x00000000, 0x00000000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00008000, 0x00008000, 0x00000000, 0x00000000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00008000, 0x00008000, 0x00000000, 0x00000000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00008000, 0x00008000, 0x00000008, 0x00000000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00008000, 0x00008000, 0x00000008, 0x00000000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00008000, 0x00008000, 0x00000008, 0x00000000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00008000, 0x00008000, 0x00000008, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00004000, 0x00004000,
0x00000008, 0x00000008, 0x00001008, 0x00000018,
0x00002000, 0x00006000, 0x00000100, 0x00004100, //
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000100, 0x00000100, 0x00000100, 0x00000100,
0x00000100, 0x00000100, 0x00000100, 0x00000100,
0x00000100, 0x00000100, 0x00000100, 0x00000100,
0x00000100, 0x00000100, 0x00000100, 0x00000100,
0x00004100, 0x00006000, 0x00004100, 0x00004100,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00002002, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000020, 0x00000020, 0x00000020, 0x00000020,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000100, 0x00002000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000100, 0x00000100, 0x00000100, 0x00000100,
0x00000100, 0x00000100, 0x00000100, 0x00000100,
0x00002000, 0x00002000, 0x00002000, 0x00002000,
0x00002000, 0x00002000, 0x00002000, 0x00002000,
0x00004100, 0x00004100, 0x00000200, 0x00000000,
0x00004000, 0x00004000, 0x00004100, 0x00006000,
0x00000300, 0x00000000, 0x00000200, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00000100, 0x00000100, 0x00000000, 0x00000000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00000100, 0x00000100, 0x00000100, 0x00000100,
0x00000100, 0x00000100, 0x00000100, 0x00000100,
0x00002000, 0x00002000, 0x00002002, 0x00000100,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000008, 0x00000000, 0x00000008, 0x00000008,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00004000, 0x00004000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0x00002000, 0x00002000, 0x00002000, 0x00002000,
0x00002000, 0x00002000, 0x00002000, 0x00002000,
0x00002000, 0x00002000, 0x00002000, 0x00002000,
0x00002000, 0x00002000, 0x00002000, 0x00002000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00000000, 0x00000000, 0x00000000, 0x00004000,
0x00004100, 0x00004000, 0xFFFFFFFF, 0xFFFFFFFF,
0x00000000, 0x00000000, 0x00000000, 0x00004000,
0x00004100, 0x00004000, 0xFFFFFFFF, 0x00004000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0xFFFFFFFF, 0xFFFFFFFF, 0x00004100, 0x00004000,
0x00004000, 0x00004000, 0x00004000, 0x00004000,
0x00004000, 0x00004000, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
0xFFFFFFFF, 0xFFFFFFFF
};
BYTE JMPGate[5] = {
0xE9, 0x00, 0x00, 0x00, 0x00 // JMP XXXXXXXX
};
BYTE BeforeStub[94] ={
0x58, // 0 pop eax
0xEB, 0x08, // 1 jmp short 0040100B
0x00, 0x00, 0x00, 0x00, // 3 dd 00000000
0x00, 0x00, 0x00, 0x00, // 7 dd 00000000
0xE8, 0x00, 0x00, 0x00, 0x00, // 11 call 00401010
0x59, // 16 pop ecx
0x81, 0xE9, 0x10, 0x10, 0x40, 0x00, // 17 sub ecx, 00401010
0x89, 0xA1, 0x03, 0x10, 0x40, 0x00, // 23 mov [ecx+401003], esp
0x89, 0x81, 0x07, 0x10, 0x40, 0x00, // 29 mov [ecx+401007], eax
0xE8, 0x36, 0x01, 0x00, 0x00, // 35 call HookProc 这里动态改变地址
0x8B, 0x44, 0x24, 0xFC, // 40 mov eax, [esp - 4]
0xE8, 0x00, 0x00, 0x00, 0x00, // 44 call 0040102D
0x59, // 49 pop ecx
0x89, 0x44, 0x24, 0xFC, // 50 mov [esp - 4], eax
0x81, 0xE9, 0x31, 0x10, 0x40, 0x00, // 54 sub ecx, 0040102D
0x8B, 0xA1, 0x03, 0x10, 0x40, 0x00, // 60 mov esp, [ecx+401003]
0x8B, 0x81, 0x07, 0x10, 0x40, 0x00, // 66 mov eax, [ecx+401007]
0x50, // 72 push eax
0x90, 0x90, 0x90, 0x90, // 73 保存入口处代码 16字节
0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90,
0x90, 0x90, 0x90, 0x90,
0xE9, 0x18, 0x01, 0x00, 0x00 // 89 jmp HookedApi
};
BYTE AfterStub[130] = {
0x58, // 00 pop eax
0xEB, 0x0C, // 01 jmp short 0040100F
0x00, 0x00, 0x00, 0x00, // 03 dd 00000000
0x00, 0x00, 0x00, 0x00, // 07 add [eax], al
0x00, 0x00, 0x00, 0x00, // 0B add [eax], al
0xE8, 0x00, 0x00, 0x00, 0x00, // 0F call 00401014
0x59, // 14 pop ecx
0x81, 0xE9, 0x14, 0x10, 0x40, 0x00, // 15 sub ecx, 00401014
0x89, 0xA1, 0x03, 0x10, 0x40, 0x00, // 1B mov [ecx+401003], esp
0x89, 0x81, 0x07, 0x10, 0x40, 0x00, // 21 mov [ecx+401007], eax
0x8D, 0x89, 0x43, 0x10, 0x40, 0x00, // 27 lea ecx, [ecx+401043] //api返回地址
0x51, // 2D push ecx //入栈,这样调用完API就回到0x43处了
0x90, // 2E nop 保存入口处代码 16字节
0x90, // 2F nop
0x90, // 30 nop
0x90, // 31 nop
0x90, // 32 nop
0x90, // 33 nop
0x90, // 34 nop
0x90, // 35 nop
0x90, // 36 nop
0x90, // 37 nop
0x90, // 38 nop
0x90, // 39 nop
0x90, // 3A nop
0x90, // 3B nop
0x90, // 3C nop
0x90, // 3D nop
0xE9, 0x57, 0x01, 0x00, 0x00, // 3E jmp 0040119A //跳回API入口
0x8B, 0x5C, 0x24, 0xFC, // 43 mov ebx, [esp-4] //api 返回地址
0xE8, 0x00, 0x00, 0x00, 0x00, // 47 call 0040104C
0x59, // 4C pop ecx
0x89, 0x5C, 0x24, 0xFC, // 4D mov [esp-4], ebx
0x81, 0xE9, 0x4C, 0x10, 0x40, 0x00, // 51 sub ecx, 0040104C
0x89, 0x81, 0x0B, 0x10, 0x40, 0x00, // 57 mov [ecx+40100B], eax
0x8B, 0xA1, 0x03, 0x10, 0x40, 0x00, // 5D mov esp, [ecx+401003]
0xE8, 0x32, 0x01, 0x00, 0x00, // 63 call 0040119A // call HookAfter
0xE8, 0x00, 0x00, 0x00, 0x00, // 68 call 0040106D
0x59, // 6D pop ecx
0x81, 0xE9, 0x6D, 0x10, 0x40, 0x00, // 6E sub ecx, 0040106D
0x8B, 0x81, 0x07, 0x10, 0x40, 0x00, // 74 mov eax, [ecx+401007]
0x50, // 7A push eax
0x8B, 0x81, 0x0B, 0x10, 0x40, 0x00, // 7B mov eax, [ecx+40100B]
0xC3 // 81 retn
};
int GetOpCodeSize(PVOID Start);
boolean SetOnBefore(PCHAR DllName,PCHAR ApiName,PVOID HookProc);
boolean SetOnAfter(PCHAR DllName,PCHAR ApiName,PVOID HookProc);
boolean SetOnBefore(PCHAR DllName,PCHAR ApiName,PVOID HookProc)
{
PVOID ApiEntry;
HMODULE DllHandle;
int ReplaceCodeSize;
BYTE OpCode[16];
LPVOID StubPtr;
DWORD Addr;
DWORD RetSize;
DllHandle = GetModuleHandle(DllName);
if (DllHandle ==0)
{
DllHandle = LoadLibrary(DllName);
if (DllHandle ==0) return false;
}
ApiEntry = GetProcAddress(DllHandle,ApiName);
if (ApiEntry == NULL) return false;
ReplaceCodeSize = GetOpCodeSize(ApiEntry);
while (ReplaceCodeSize < 5)
ReplaceCodeSize += GetOpCodeSize((PVOID)((DWORD)ApiEntry + (DWORD)ReplaceCodeSize));
if (ReplaceCodeSize > 16) return false;
if (VirtualProtect(ApiEntry,ReplaceCodeSize,PAGE_READWRITE,NULL))
return false;
CopyMemory(OpCode, ApiEntry, ReplaceCodeSize);
StubPtr = VirtualAlloc(NULL, sizeof(BeforeStub), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (StubPtr == NULL) return false;
CopyMemory(StubPtr, BeforeStub, sizeof(BeforeStub));
Addr = (DWORD)HookProc - (DWORD)StubPtr - 35 - 5;
*(DWORD *) ((DWORD)StubPtr + 36) = Addr;
Addr = (DWORD)ApiEntry + ReplaceCodeSize - (DWORD)StubPtr - 89 - 5;
*(DWORD *) ((DWORD)StubPtr + 90) = Addr;
CopyMemory((LPVOID)((DWORD)StubPtr + 73), OpCode, ReplaceCodeSize);
Addr = (DWORD)StubPtr - (DWORD)ApiEntry - 5;
*(DWORD*)(JMPGate + 1) = Addr;
WriteProcessMemory(GetCurrentProcess(), ApiEntry, JMPGate, sizeof(JMPGate), (DWORD*)RetSize);
return true;
}
boolean SetOnAfter(PCHAR DllName,PCHAR ApiName,PVOID HookProc)
{
PVOID ApiEntry;
HMODULE DllHandle;
int ReplaceCodeSize;
BYTE OpCode[16];
LPVOID StubPtr;
DWORD Addr;
DWORD RetSize;
DllHandle = GetModuleHandle(DllName);
if (DllHandle ==0)
{
DllHandle = LoadLibrary(DllName);
if (DllHandle ==0) return false;
}
ApiEntry = GetProcAddress(DllHandle,ApiName);
if (ApiEntry == NULL) return false;
ReplaceCodeSize = GetOpCodeSize(ApiEntry);
while (ReplaceCodeSize < 5)
ReplaceCodeSize += GetOpCodeSize((PVOID)((DWORD)ApiEntry + (DWORD)ReplaceCodeSize));
if (ReplaceCodeSize > 16) return false;
if (VirtualProtect(ApiEntry,ReplaceCodeSize,PAGE_READWRITE,NULL))
return false;
CopyMemory(OpCode, ApiEntry, ReplaceCodeSize);
StubPtr = VirtualAlloc(NULL, sizeof(AfterStub), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (StubPtr == NULL) return false;
CopyMemory(StubPtr, AfterStub, sizeof(AfterStub));
Addr = (DWORD)HookProc - (DWORD)StubPtr - 0x63 - 5;
*(DWORD *) ((DWORD)StubPtr + 0x64) = Addr;
Addr = (DWORD)ApiEntry + ReplaceCodeSize - (DWORD)StubPtr - 0x3E - 5;
*(DWORD *) ((DWORD)StubPtr + 0x3F) = Addr;
CopyMemory((LPVOID)((DWORD)StubPtr + 0x2E), OpCode, ReplaceCodeSize);
Addr = (DWORD)StubPtr - (DWORD)ApiEntry - 5;
*(DWORD*)(JMPGate + 1) = Addr;
WriteProcessMemory(GetCurrentProcess(), ApiEntry, JMPGate, sizeof(JMPGate), (DWORD*)RetSize);
return true;
}
int GetOpCodeSize(PVOID Start)
{
/* 为了防止某些网站转贴时斩头去尾留中间,将信息在此COPY一份
{
Name: API Hook Lib for C
Version: 0.2
Author: coded by xIkUg/RCT/CCG modified by 海风月影[NE365]
HomePage: http://www.wintoolspro.com, http://debugman.wintoolspro.com
CreateDate: 2006-12-03
ModifiedDate:2007-3-21
}
*/
DWORD* Tlb=(DWORD*)MaskTable;
PBYTE pOPCode;
DWORD t, c;
BYTE dh, dl, al;
int OpCodeSize =-1;
t = 0;
pOPCode = (PBYTE) Start;
c = 0;
do {
t &= 0x0F7;
c = *(BYTE *) pOPCode++;
t |= Tlb[c] ;
} while( ((t & 0x000000FF) & 8) != 0);
if ((c == 0x0F6) || (c == 0x0F7))
{
t |= 0x00004000;
if ( (0x38 & *(BYTE *) pOPCode++) == 0)
t |= 0x00008000;
}
else if (c == 0x0CD)
{
t |= 0x00000100;
if ( (*(BYTE *) pOPCode++) == 0x20)
t |= 0x00000400;
}
else if (c == 0x0F)
{
al = *(BYTE *) pOPCode++;
t |= Tlb[al + 0x100];
if (t == 0xFFFFFFFF)
return OpCodeSize;
}
if ((((t & 0x0000FF00) >> 8) & 0x80) != 0)
{
dh = (t & 0x0000FF00) >> 8;
dh ^= 0x20;
if ((c & 1) == 0)
dh ^= 0x21;
t &= 0xFFFF00FF;
t |= (dh << 8);
}
if ((((t & 0x0000FF00) >> 8) & 0x40) != 0 )
{
al = *(BYTE *) pOPCode++;
c = (DWORD)al;
c |= (al << 8);
c &= 0xC007;
if ( (c & 0x0000FF00) != 0xC000 )
{
if ( ((t & 0x000000FF) & 0x10) == 0)
{
if ((c & 0x000000FF) == 4)
{
al = *(BYTE *) pOPCode++;
al &= 7;
c &= 0x0000FF00;
c |= al;
}
if ((c & 0x0000FF00) != 0x4000)
{
if ((c & 0x0000FF00) == 0x8000) t |= 4;
else if (c==5) t |= 4;
}
else
t |= 1;
}
else
{
if (c != 6)
{
if((c & 0x0000FF00) == 0x4000)
t |= 1;
else if ((c & 0x0000FF00) == 0x8000)
t |= 2;
}
else
t |= 2;
}
}
}
if ((((t & 0x000000FF)) & 0x20) != 0)
{
dl = t & 0x000000FF;
dl ^= 2;
t &= 0xFFFFFF00;
t |= dl;
if ((dl & 0x10) == 0)
{
dl ^= 6;
t &= 0xFFFFFF00;
t |= dl;
}
}
if ((((t & 0x0000FF00) >> 8) & 0x20) != 0)
{
dh = (t & 0x0000FF00) >> 8;
dh ^= 2;
t &= 0xFFFF00FF;
t |= (dh << 8);
if ((dh & 0x10) == 0)
{
if (dh & 0x40) //是否是 0x6x
dh ^= 1; // 当dh = 0x2x 这里计算多2,当=62的时候却是 异或1
t &= 0xFFFFFF00;
t |= dh;
}
}
OpCodeSize = (DWORD) pOPCode - (DWORD) Start;
t &= 0x707;
OpCodeSize += t & 0x000000FF;
OpCodeSize += (t & 0x0000FF00) >> 8;
/*
一旦OpCode是 66 开头,会出问题
如,第一个例子
66:814D E4 0103 or word ptr ss:[ebp-1C], 301
计算出来是8,其实是 814D E4 01030000 的7位 加上66一个字节
而,第二个例子
66:8906 mov word ptr ds:[esi], ax
正确,是3
原因是这样的
引用老罗的Learningopcode:
//////////////////////////////////////////////////////////////////////////
现在我们将要学习剩下的几个Prefixes,它们可以被划分为5个集合,分别是:
Change DEFAULT operand size. (66)
Change DEFAULT address size. (67)
Repeat prefixes. (F2, F3)
Segment override prefixes(change DEFAULT segment). (2E, 36, 3E, 26, 64, 65)
LOCK prefix. (F0)
prefix 66的作用是切换默认的操作数大小。请注意我们并没有说“指定”,
而是“切换”!反映到这个例子中,就是“切换默认的32位操作数到16位”
,而不是“指定操作数的大小为16位”。
也许并不是所有情况下的操作数大小都可以随意改变的。
假如这个改变是不允许的,那么它就会被忽略。
//////////////////////////////////////////////////////////////////////////
因此,第一个例子操作数从32位变成了16位,第二个例子无法改变,所以就没变
因此,此算法没有考虑prefix 66开头的变化,要加上66开头的处理
66也占一个字节,因此,第一个其实是 8
*/
/*
单独处理 66 开头的问题
1字节66 ,1字节操作码,4字节操作数,因此至少要大于等于6以上
如
0040A339 66:B8 FF00 mov ax, 0FF
0040A33D 0000 add byte ptr ds:[eax], al
★我们这里假设windows 32位系统中没有单独操作16位的OpCode(事实估计也是这样的)
*/
if (((*(char*)Start) & 0x000000FF) == 0x66)
if ( OpCodeSize >= 6)
OpCodeSize -= 2; //减2处理 ,将 dword 型转成 word 型
return OpCodeSize;
}
int main()
{
//Just for test
HMODULE hModule;
hModule = GetModuleHandle("Kernel32.dll");
PVOID ApiEntry = GetProcAddress(hModule,"GetVolumeInformationW");
int a,b,i;
b = GetOpCodeSize(ApiEntry);
a = 0;
while (a < 507)
{
for (i = 0;i < b; i++)
{
printf("%02X ",(*(char *)((DWORD)ApiEntry + (DWORD)a +(DWORD)i)) & 0x000000FF);
}
a+=b;
printf(" %d\n",b);
b = GetOpCodeSize((PVOID)((DWORD)ApiEntry +(DWORD)a));
}
return 0;
}
GetOpCodeSize()对某些命令会算错,经多次试验,排查,发现问题在这里
if ((dh & 0x10) == 0)
{
dh ^= 6; // 这里不能异或6,是异或1,而且不是所以情况都要异或
t &= 0xFFFFFF00;
t |= dh;
}
改成这个,就可以了(我没研究到底为什么,反正能用就行)
if (dh & 0x40) //是否是 0x6x
dh ^= 1; // 当dh = 0x2x 这里计算多2,当=62的时候却是 异或1
还有一个问题,应该是GetOpCodeSize本身的问题了
/*
一旦OpCode以Prefix 66 开头,会出问题
如,第一个例子
66:814D E4 0103 or word ptr ss:[ebp-1C], 301
计算出来是8,其实是 814D E4 01030000 的7位 加上66一个字节
而,第二个例子
66:8906 mov word ptr ds:[esi], ax
正确,是3
原因是这样的
引用老罗的Learningopcode:
//////////////////////////////////////////////////////////////////////////
现在我们将要学习剩下的几个Prefixes,它们可以被划分为5个集合,分别是:
Change DEFAULT operand size. (66)
Change DEFAULT address size. (67)
Repeat prefixes. (F2, F3)
Segment override prefixes(change DEFAULT segment). (2E, 36, 3E, 26, 64, 65)
LOCK prefix. (F0)
prefix 66的作用是切换默认的操作数大小。请注意我们并没有说“指定”,
而是“切换”!反映到这个例子中,就是“切换默认的32位操作数到16位”
,而不是“指定操作数的大小为16位”。
也许并不是所有情况下的操作数大小都可以随意改变的。
假如这个改变是不允许的,那么它就会被忽略。
//////////////////////////////////////////////////////////////////////////
因此,第一个例子操作数从32位变成了16位,第二个例子无法改变,所以就没变
因此,此算法没有考虑prefix 66开头的变化,要加上66开头的处理
66也占一个字节,因此,第一个其实是 8
*/
这里我是在最后进行修正的,前面那些分支就没去管它
修正如下:
/*
单独处理 66 开头的问题
1字节66 ,1字节操作码,4字节操作数,因此至少要大于等于6以上
如
0040A339 66:B8 FF00 mov ax, 0FF
0040A33D 0000 add byte ptr ds:[eax], al
★我们这里假设windows 32位系统中没有单独操作16位的OpCode(事实估计也是这样的
)
*/
if (((*(char*)Start) & 0x000000FF) == 0x66) // 单独处理 66 开头的问题
if ( OpCodeSize >= 6) //1字节66 ,1字节操作码,4字节操作数,因此至少要大于等于6以上
OpCodeSize -= 2; //减2处理 ,将 dword 型转成 word 型
上面的代码里有个main(),我测试了一下GetVolumeInformationW这个API函数,一共500+个字节,用OD反汇编对照了一下,OpCode长度没判断错,暂且认为它已经正确了吧,下面就可以用GetOpCodeSize干点坏事了,哈哈
thx to xIkUg,luocong
[培训]《安卓高级研修班(网课)》月薪三万计划,掌
握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法