解开后如何调用原始函数? [英] How call original function after unhook it?
问题描述
我正在挂钩
LdrLoadDll()功能并取得成功。现在我想对代码做一个小改动,当不是特定的dll加载时,调用原始函数..
我尝试了以下实现,但应用程序崩溃了调用原始函数。
首先我解开了api
之后,我将一个变量归结为 $ b $的原型b LdrLoadDll()原始功能并将其称为
为什么会失败?
见:
#include" stdafx.h"
#include< Windows.h>
#include< shlwapi.h>
#include< strsafe.h>
#include< winternl.h>
#include< iostream>
#include< stdio.h>
#pragma comment(lib," shlwapi.lib")
using namespace std;
bool CheckSubstring(string firstString,string secondString){
if(secondString.size()> firstString.size())
return false;
for(int i = 0; i< firstString.size(); i ++){
int j = 0;
if(firstString [i] == secondString [j]){
int k = i;
while(firstString [i] == secondString [j]&& j< secondString.size()){
j ++;
i ++;
}
if(j == secondString.size())
返回true;
else
i = k;
}
}
返回false;
}
LPBYTE original = 0;
DWORD oldFuncAdr = 0;
void HookLdrLoadDll();
void UnHookLdrLoadDll();
typedef NTSTATUS(NTAPI * pLdrLoadDll)(PWCHAR,ULONG,PUNICODE_STRING,PHANDLE);
#define STATUS_ACCESS_DENIED 0xC0000022L
NTSTATUS NTAPI FakeLdrLoadDll(PWCHAR PathToFile,ULONG Flags,PUNICODE_STRING ModuleFileName,PHANDLE ModuleHandle)
{
// === $==============================================
UnHookLdrLoadDll();
pLdrLoadDll fnLdrLoadDll =(pLdrLoadDll)oldFuncAdr;
// ======================================== ==========
size_t i;
char * pMBBuffer =(char *)malloc(BUFFER_SIZE);
wchar_t * pWCBuffer = PathFindFileNameW(ModuleFileName-> Buffer);
wcstombs_s(& i,pMBBuffer,(size_t)BUFFER_SIZE,pWCBuffer,(size_t)BUFFER_SIZE);
if(CheckSubstring(pMBBuffer," aaa")||
CheckSubstring(pMBBuffer," bbb")||
CheckSubstring(pMBBuffer," ccc")| |
CheckSubstring(pMBBuffer," ddd")||
CheckSubstring(pMBBuffer," eee")||
CheckSubstring(pMBBuffer," fff"))
{
HookLdrLoadDll();
if(pMBBuffer)
{
free(pMBBuffer);
}
返回STATUS_ACCESS_DENIED;
}
if(pMBBuffer)
{
free(pMBBuffer);
}
// =================================== ==================================
返回fnLdrLoadDll(PathToFile,Flags,ModuleFileName ,ModuleHandle);
// ======================================== ==============================
}
void HookLdrLoadDll()
{
HMODULE hModule = NULL;
NTSTATUS newFuncAdr =(NTSTATUS)FakeLdrLoadDll;
DWORD continueAdr = 0;
DWORD jmpAdr = 0;
LPBYTE pOldFuncAdr = 0;
LPBYTE pJmpAdr = 0;
DWORD oldProtect;
DWORD i = 0;
hModule = LoadLibrary(TEXT(" ntdll.dll"));
oldFuncAdr =(DWORD)GetProcAddress(hModule," LdrLoadDll");
jmpAdr = newFuncAdr - oldFuncAdr - 5;
pOldFuncAdr =(LPBYTE)oldFuncAdr;
pJmpAdr =(LPBYTE)(& jmpAdr);
if(!VirtualProtect(pOldFuncAdr,5,PAGE_EXECUTE_READWRITE,& oldProtect))
{
return;
}
original = pOldFuncAdr;
for(i = 0; i< 5; i ++)
{
original [i] = pOldFuncAdr [i];
}
pOldFuncAdr [0] =(BYTE)0xE9;
for(i = 0; i< 5; i ++)
{
pOldFuncAdr [i + 1] = pJmpAdr [i];
}
if(!VirtualProtect(pOldFuncAdr,5,oldProtect,& oldProtect))
{
return;
}
}
void UnHookLdrLoadDll()
{
LPBYTE pOldFuncAdr = 0;
DWORD i = 0;
DWORD oldProtect;
pOldFuncAdr =(LPBYTE)oldFuncAdr;
VirtualProtect(pOldFuncAdr,
5,
PAGE_EXECUTE_READWRITE,
& oldProtect);
for(i = 0; i< 5; i ++)
{
pOldFuncAdr [i] = original [i];
}
VirtualProtect(pOldFuncAdr,
5,
oldProtect,
& oldProtect);
}
可能'LPBYTE original = 0'应替换为
'BYTE original [5]应删除和'original = pOldFuncAdr'。
参见:
https://www.microsoft.com/en-us/research/project/弯路/ 。跨度>
I'm hooking the
LdrLoadDll() function and have success. Now i want make a small change on code, to when not is a specific dll load, call original function..
I tried the following implementation but the application crashes when call original function.
First i unhook the api
After, i attribs to a variable the prototype of
LdrLoadDll() the original function and call it
Why this is failing?
See:
#include "stdafx.h" #include <Windows.h> #include <shlwapi.h> #include <strsafe.h> #include <winternl.h> #include <iostream> #include <stdio.h> #pragma comment(lib, "shlwapi.lib") using namespace std; bool CheckSubstring(string firstString, string secondString){ if (secondString.size() > firstString.size()) return false; for (int i = 0; i < firstString.size(); i++){ int j = 0; if (firstString[i] == secondString[j]){ int k = i; while (firstString[i] == secondString[j] && j < secondString.size()){ j++; i++; } if (j == secondString.size()) return true; else i = k; } } return false; } LPBYTE original = 0; DWORD oldFuncAdr = 0; void HookLdrLoadDll(); void UnHookLdrLoadDll(); typedef NTSTATUS(NTAPI *pLdrLoadDll)(PWCHAR, ULONG, PUNICODE_STRING, PHANDLE); #define STATUS_ACCESS_DENIED 0xC0000022L NTSTATUS NTAPI FakeLdrLoadDll(PWCHAR PathToFile, ULONG Flags, PUNICODE_STRING ModuleFileName, PHANDLE ModuleHandle) { //================================================== UnHookLdrLoadDll(); pLdrLoadDll fnLdrLoadDll = (pLdrLoadDll)oldFuncAdr; //================================================== size_t i; char *pMBBuffer = (char *)malloc(BUFFER_SIZE); wchar_t*pWCBuffer = PathFindFileNameW(ModuleFileName->Buffer); wcstombs_s(&i, pMBBuffer, (size_t)BUFFER_SIZE, pWCBuffer, (size_t)BUFFER_SIZE); if (CheckSubstring(pMBBuffer, "aaa") || CheckSubstring(pMBBuffer, "bbb") || CheckSubstring(pMBBuffer, "ccc") || CheckSubstring(pMBBuffer, "ddd") || CheckSubstring(pMBBuffer, "eee") || CheckSubstring(pMBBuffer, "fff")) { HookLdrLoadDll(); if (pMBBuffer) { free(pMBBuffer); } return STATUS_ACCESS_DENIED; } if (pMBBuffer) { free(pMBBuffer); } //===================================================================== return fnLdrLoadDll(PathToFile, Flags, ModuleFileName, ModuleHandle); //====================================================================== } void HookLdrLoadDll() { HMODULE hModule = NULL; NTSTATUS newFuncAdr = (NTSTATUS)FakeLdrLoadDll; DWORD continueAdr = 0; DWORD jmpAdr = 0; LPBYTE pOldFuncAdr = 0; LPBYTE pJmpAdr = 0; DWORD oldProtect; DWORD i = 0; hModule = LoadLibrary(TEXT("ntdll.dll")); oldFuncAdr = (DWORD)GetProcAddress(hModule, "LdrLoadDll"); jmpAdr = newFuncAdr - oldFuncAdr - 5; pOldFuncAdr = (LPBYTE)oldFuncAdr; pJmpAdr = (LPBYTE)(&jmpAdr); if (!VirtualProtect(pOldFuncAdr, 5, PAGE_EXECUTE_READWRITE, &oldProtect)) { return; } original = pOldFuncAdr; for (i = 0; i < 5; i++) { original[i] = pOldFuncAdr[i]; } pOldFuncAdr[0] = (BYTE)0xE9; for (i = 0; i < 5; i++) { pOldFuncAdr[i + 1] = pJmpAdr[i]; } if (!VirtualProtect(pOldFuncAdr, 5, oldProtect, &oldProtect)) { return; } } void UnHookLdrLoadDll() { LPBYTE pOldFuncAdr = 0; DWORD i = 0; DWORD oldProtect; pOldFuncAdr = (LPBYTE)oldFuncAdr; VirtualProtect(pOldFuncAdr, 5, PAGE_EXECUTE_READWRITE, &oldProtect); for (i = 0; i < 5; i++) { pOldFuncAdr[i] = original[i]; } VirtualProtect(pOldFuncAdr, 5, oldProtect, &oldProtect); }
Probably ‘LPBYTE original = 0’ should be replaced with ‘BYTE original[5]’, and ‘original = pOldFuncAdr’ should be removed.
See also: https://www.microsoft.com/en-us/research/project/detours/.
这篇关于解开后如何调用原始函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!