Last active
December 18, 2015 11:19
-
-
Save kobake/5774678 to your computer and use it in GitHub Desktop.
APIフック (Cライブラリ関数やWindowsAPIの書き換え) と、その応用例 ref: http://qiita.com/items/8d3d3637c7af0b270098
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
… | |
Module:KERNEL32.dll Hint:234, Name:EncodePointer | |
Module:KERNEL32.dll Hint:532, Name:GetModuleFileNameW | |
Module:USER32.dll Hint:526, Name:MessageBoxA | |
Module:imagehlp.dll Hint:18, Name:ImageDirectoryEntryToData | |
… | |
Module:MSVCR100D.dll Hint:289, Name:_CRT_RTC_INITW | |
Module:MSVCR100D.dll Hint:1289, Name:_wassert | |
Module:MSVCR100D.dll Hint:1499, Name:getchar ← 今回はこれを書き替えてみます | |
Module:MSVCR100D.dll Hint:1474, Name:fopen | |
Module:MSVCR100D.dll Hint:1560, Name:printf | |
… |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <windows.h> | |
#include <imagehlp.h> | |
#pragma comment(lib,"imagehlp.lib") | |
void* RewriteFunctionImp(const char* szRewriteModuleName, const char* szRewriteFunctionName, void* pRewriteFunctionPointer) | |
{ | |
for(int i = 0; i < 2; i++){ | |
// ベースアドレス | |
DWORD dwBase = 0; | |
if(i == 0){ | |
if(szRewriteModuleName){ | |
dwBase = (DWORD)(intptr_t)::GetModuleHandleA(szRewriteModuleName); | |
} | |
} | |
else if(i == 1){ | |
dwBase = (DWORD)(intptr_t)GetModuleHandle(NULL); | |
} | |
if(!dwBase)continue; | |
// イメージ列挙 | |
ULONG ulSize; | |
PIMAGE_IMPORT_DESCRIPTOR pImgDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData((HMODULE)(intptr_t)dwBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize); | |
for(; pImgDesc->Name; pImgDesc++){ | |
const char* szModuleName = (char*)(intptr_t)(dwBase+pImgDesc->Name); | |
// THUNK情報 | |
PIMAGE_THUNK_DATA pFirstThunk = (PIMAGE_THUNK_DATA)(intptr_t)(dwBase+pImgDesc->FirstThunk); | |
PIMAGE_THUNK_DATA pOrgFirstThunk = (PIMAGE_THUNK_DATA)(intptr_t)(dwBase+pImgDesc->OriginalFirstThunk); | |
// 関数列挙 | |
for(;pFirstThunk->u1.Function; pFirstThunk++, pOrgFirstThunk++){ | |
if(IMAGE_SNAP_BY_ORDINAL(pOrgFirstThunk->u1.Ordinal))continue; | |
PIMAGE_IMPORT_BY_NAME pImportName = (PIMAGE_IMPORT_BY_NAME)(intptr_t)(dwBase+(DWORD)pOrgFirstThunk->u1.AddressOfData); | |
if(!szRewriteFunctionName){ | |
// 表示のみ | |
printf("Module:%s Hint:%d, Name:%s\n", szModuleName, pImportName->Hint, pImportName->Name); | |
} | |
else{ | |
// 書き換え判定 | |
if(stricmp((const char*)pImportName->Name, szRewriteFunctionName) != 0)continue; | |
// 保護状態変更 | |
DWORD dwOldProtect; | |
if( !VirtualProtect(&pFirstThunk->u1.Function, sizeof(pFirstThunk->u1.Function), PAGE_READWRITE, &dwOldProtect) ) | |
return NULL; // エラー | |
// 書き換え | |
void* pOrgFunc = (void*)(intptr_t)pFirstThunk->u1.Function; // 元のアドレスを保存しておく | |
WriteProcessMemory(GetCurrentProcess(), &pFirstThunk->u1.Function, &pRewriteFunctionPointer, sizeof(pFirstThunk->u1.Function), NULL); | |
pFirstThunk->u1.Function = (DWORD)(intptr_t)pRewriteFunctionPointer; | |
// 保護状態戻し | |
VirtualProtect(&pFirstThunk->u1.Function, sizeof(pFirstThunk->u1.Function), dwOldProtect, &dwOldProtect); | |
return pOrgFunc; // 元のアドレスを返す | |
} | |
} | |
} | |
} | |
return NULL; | |
} | |
void* RewriteFunction(const char* szRewriteModuleName, const char* szRewriteFunctionName, void* pRewriteFunctionPointer) | |
{ | |
return RewriteFunctionImp(szRewriteModuleName, szRewriteFunctionName, pRewriteFunctionPointer); | |
} | |
void PrintFunctions() | |
{ | |
printf("----\n"); | |
RewriteFunctionImp(NULL, NULL, NULL); | |
printf("----\n"); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! 関数コール書き換え。 | |
@param [in] szRewriteModuleName 書き替えたいモジュール名 | |
@param [in] szRewriteFunctionName 書き替えたい関数名 | |
@param [in] pRewriteFunctionAddress 書き替え後の関数アドレス | |
@return 元の関数アドレス | |
*/ | |
void* RewriteFunction( | |
const char* szRewriteModuleName, | |
const char* szRewriteFunctionName, | |
void* pRewriteFunctionAddress | |
); | |
void PrintFunctions(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <stdio.h> | |
#include "rewrite.h" | |
void __cdecl _wassert2(const wchar_t* expr, const wchar_t* filename, unsigned lineno) | |
{ | |
// ※ここで filename や lineno で条件チェックを行うほうがより丁寧ですが | |
// とりあえず今回は全スキップしてみました | |
} | |
int main() | |
{ | |
void* p = RewriteFunction("MSVCR100D.dll", "_wassert", _wassert2); | |
printf("start\n"); | |
assert(0); // このassertはスルーされる | |
printf("end\n"); | |
RewriteFunction("MSVCR100D.dll", "_wassert", p); // 戻す | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <Windows.h> | |
#include "rewrite.h" | |
typedef HANDLE (WINAPI *CreateFileTypeW)( | |
LPCWSTR name, DWORD dw1, DWORD dw2, LPSECURITY_ATTRIBUTES lps, | |
DWORD dw3, DWORD dw4, HANDLE h); | |
CreateFileTypeW org; | |
HANDLE WINAPI MyCreateFileW( | |
LPCWSTR name, DWORD dw1, DWORD dw2, LPSECURITY_ATTRIBUTES lps, | |
DWORD dw3, DWORD dw4, HANDLE h) | |
{ | |
printf("CreateFileW: %ls\n", name); | |
return org(name, dw1, dw2, lps, dw3, dw4, h); | |
} | |
int main() | |
{ | |
org = (CreateFileTypeW)RewriteFunction("KERNEL32.dll", "CreateFileW", MyCreateFileW); | |
fopen("app.fopen", "rb"); | |
CreateFileW(L"app.createfileW", GENERIC_READ, 0, NULL, | |
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | |
CreateFileA("app.createfileA", GENERIC_READ, 0, NULL, | |
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); | |
RewriteFunction("KERNEL32.dll", "CreateFileW", org); // 戻す | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <time.h> | |
#include "rewrite.h" | |
typedef __time64_t (__cdecl *time64type)(__time64_t* t); | |
time64type orgtime; | |
__time64_t __cdecl mytime64(__time64_t* t) | |
{ | |
__time64_t value = orgtime(t); | |
value += 60 * 60 * 24; // 1日進める | |
if(t)*t = value; | |
return value; | |
} | |
int main() | |
{ | |
printf("time: %d\n", time(NULL)); | |
orgtime = (time64type)RewriteFunction("MSVCR100D.dll", "_time64", mytime64); | |
printf("time: %d\n", time(NULL)); | |
RewriteFunction("MSVCR100D.dll", "_time64", orgtime); // 戻す | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "rewrite.h" | |
int main() | |
{ | |
PrintFunctions(); | |
if(0){ | |
// ※実際にプログラム内で使われている関数が表示されるので | |
// 書き替えたい関数が決まっていればダミーでも良いので | |
// どこかで呼んでおく。 | |
getchar(); | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "rewrite.h" | |
int __cdecl mygetchar(void) | |
{ | |
return 'A'; | |
} | |
int main() | |
{ | |
void* p = RewriteFunction("MSVCR100D.dll", "getchar", mygetchar); | |
printf("%c\n", getchar()); | |
RewriteFunction("MSVCR100D.dll", "getchar", p); // 戻す | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_Check_return_ _CRTIMP int __cdecl getchar(void); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment