#include <windows.h> 
#include <iostream> 
using namespace std; typedef int (WINAPI *pDeleteFilef)(LPCTSTR lpFileName); char szOldMessageBox[5] = {0}; 
char szJmpMyMessageBox[5] = {(char)0xe9}; 
pDeleteFilef pDeleteFile = NULL; 
  
int WINAPI MyDeleteFile(LPCTSTR lpFileName)  

WriteProcessMemory((void*)-1, pDeleteFile, szOldMessageBox, 5, NULL); MessageBox(NULL,lpFileName,lpFileName,MB_OK);WriteProcessMemory((void*)-1, pDeleteFile, szJmpMyMessageBox, 5, NULL); return 0; 
} int main() 

DWORD dwJmpAddr = 0; 
HMODULE hModule = LoadLibrary("kernel32.Dll"); 
pDeleteFile = (pDeleteFilef)GetProcAddress(hModule, "DeleteFileA"); 
dwJmpAddr = (DWORD)MyDeleteFile - (DWORD)pDeleteFile - 5; 
memcpy(szJmpMyMessageBox + 1, &dwJmpAddr, 4); 
FreeLibrary(hModule); 
ReadProcessMemory((void*)-1, pDeleteFile, szOldMessageBox, 5, NULL);
WriteProcessMemory((void*)-1, pDeleteFile, szJmpMyMessageBox, 5, NULL);
DeleteFile ("c:\1.exe");
return 0; 
}
上面是全部代码 修改也成功。 但是返回 lpFileName 的时候 出现乱码。。 这是什么原因。

解决方案 »

  1.   

    #include <windows.h>
    #include <iostream>
    // 定义API挂接项结构
    typedef struct _HOOK_ITEM {
    DWORD dwAddr ; // IAT项所在地址
    DWORD dwOldValue ; // IAT项的原始函数地址
    DWORD dwNewValue ; // IAT项的新函数地址
    } HOOK_ITEM, *PHOOK_ITEM ;
    HOOK_ITEM HookItem = {0} ; // 定义IAT项,用于保存MessageBoxA的IAT项信息// 定义MessageBoxA函数原型
    typedef int (WINAPI* PFNMessageBoxA)(LPCTSTR lpFileName) ;// 定义重定向API的实现函数
    BOOL WINAPI RedirectApi ( PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc, PHOOK_ITEM pItem ) ;// 自定义的MessageBoxA函数
    // 实现对原始MessageBoxA的输入、输出参数的监控,甚至是取消调用
    int WINAPI NEW_DeleteFileA(LPCTSTR lpFileName )
    {PFNMessageBoxA pfnMessageBoxA = (PFNMessageBoxA)HookItem.dwOldValue ;// 输出测试信息,
    // 如果这里直接调用MessageBoxA,就进入无限循环
    //pfnMessageBoxA ( hWnd, "这是API重定向过程的消息框", "测试", 0 ) ;
    MessageBoxA ( 0, lpFileName, "测试", 0 ) ;
    // 调用原函数
    int ret = pfnMessageBoxA (lpFileName) ;// 此处可以查看/修改调用原函数的返回值
    // ……return ret ;
    }int main( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
    {
    // 重定向API
    if ( !RedirectApi ( "USER32.dll", "DeleteFileA", (DWORD)NEW_DeleteFileA, &HookItem ) )
    MessageBoxA ( 0, "失败", "测试", 0 ) ;
    else
    MessageBoxA ( 0, "成功", "测试", 0 ) ;
    DeleteFile ("C:\1.EXE");return 0 ;
    }// 实现重定向API
    // 参数pDllName:目标API所在的DLL名称
    // 参数pFunName:目标API名称
    // 参数dwNewProc:自定义的函数地址
    // 参数pItem:用于保存IAT项信息
    BOOL WINAPI RedirectApi ( PCHAR pDllName, PCHAR pFunName, DWORD dwNewProc, PHOOK_ITEM pItem )
    {
    // 检查参数是否合法
    if ( pDllName == NULL || pFunName == NULL || !dwNewProc || !pItem )
    return FALSE ;// 检测目标模块是否存在
    char szTempDllName[256] = {0} ;
    DWORD dwBaseImage = (DWORD)GetModuleHandle(NULL) ;
    if ( dwBaseImage == 0 )
    return FALSE ;// 取得PE文件头信息指针
    PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)dwBaseImage ;
    PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)(dwBaseImage + (pDosHeader->e_lfanew)) ;
    PIMAGE_OPTIONAL_HEADER32 pOptionalHeader = &(pNtHeader->OptionalHeader) ;
    PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeader + 0x18 + pNtHeader->FileHeader.SizeOfOptionalHeader ) ;// 遍历导入表
    PIMAGE_THUNK_DATA pThunk, pIAT ;
    PIMAGE_IMPORT_DESCRIPTOR pIID = (PIMAGE_IMPORT_DESCRIPTOR)(dwBaseImage+pOptionalHeader->DataDirectory[1].VirtualAddress ) ;
    while ( pIID->FirstThunk )
    {
    // 检测是否目标模块
    if ( strcmp ( (PCHAR)(dwBaseImage+pIID->Name), pDllName ) )
    {
    pIID++ ;
    continue ;
    }pIAT = (PIMAGE_THUNK_DATA)( dwBaseImage + pIID->FirstThunk ) ;
    if ( pIID->OriginalFirstThunk )
    pThunk = (PIMAGE_THUNK_DATA)( dwBaseImage + pIID->OriginalFirstThunk ) ;
    else
    pThunk = pIAT ;// 遍历IAT
    DWORD dwThunkValue = 0 ;
    while ( ( dwThunkValue = *((DWORD*)pThunk) ) != 0 )
    {
    if ( ( dwThunkValue & IMAGE_ORDINAL_FLAG32 ) == 0 )
    {
    // 检测是否目标函数
    if ( strcmp ( (PCHAR)(dwBaseImage+dwThunkValue+2), pFunName ) == 0 )
    {
    // 填充函数重定向信息
    pItem->dwAddr = (DWORD)pIAT ;
    pItem->dwOldValue = *((DWORD*)pIAT) ;
    pItem->dwNewValue = dwNewProc;// 修改IAT项
    DWORD dwOldProtect = 0 ;
    VirtualProtect ( pIAT, 4, PAGE_READWRITE, &dwOldProtect ) ;
    *((DWORD*)pIAT) = dwNewProc ;
    VirtualProtect ( pIAT, 4, PAGE_READWRITE, &dwOldProtect ) ;
    return TRUE ;
    }
    }pThunk ++ ;
    pIAT ++ ;
    }pIID ++ ;
    }return FALSE ;
    }上面这一段代码直接失败了。 不知道原因为何麻烦高手给说下 嘿嘿。。