西裤哥的 Hook Api Lib 0.2 For C
生活随笔
收集整理的這篇文章主要介紹了
西裤哥的 Hook Api Lib 0.2 For C
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
標 題: 【分享】西褲哥的 Hook Api Lib 0.2 For C
作 者: 海風月影
時 間: 2007-03-21,15:11:30
鏈 接: http://bbs.pediy.com/showthread.php?t=41387
對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)?//是否是?0x6xdh?^=?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
作 者: 海風月影
時 間: 2007-03-21,15:11:30
鏈 接: http://bbs.pediy.com/showthread.php?t=41387
對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)?//是否是?0x6xdh?^=?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
轉載于:https://www.cnblogs.com/pearry/archive/2011/03/17/1986998.html
總結
以上是生活随笔為你收集整理的西裤哥的 Hook Api Lib 0.2 For C的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OleCommand的SqlText占位
- 下一篇: 照亮云备份的“钱”途