【獻寶】利用DebugAPI做一些原先手工完成的動作,我用這種方法做過記憶體補丁,記憶體序號產生器等,完全VC編譯 (6千字)

看雪資料發表於2002-12-27

內容:
這段程式碼針對的是LanTalk XP v2.7.1.0 Build 7123

// LanTalk_ldr.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include <stdlib.h>
#include "shlwapi.h"

#pragma comment(lib, "shlwapi.lib")

typedef struct
{
    LPVOID lpAddr;
    BYTE  byData;
    DWORD  nCount;
} BPDATA;

BPDATA g_bpData[10] = {0};
BOOL SetBreakPoint(HANDLE hProcess, LPVOID lpAddr, UINT nNum)
{
    if (nNum >= sizeof(g_bpData) / sizeof(BPDATA)) return FALSE;

    BYTE byTemp;
    DWORD dwNewProt, dwOldProt;

    VirtualProtectEx(hProcess, lpAddr, 1, PAGE_EXECUTE_READWRITE, &dwOldProt);
    BOOL bOK = ReadProcessMemory(hProcess, lpAddr, &byTemp, 1, NULL);
    if (!bOK) goto End;

    g_bpData[nNum].lpAddr = lpAddr;
    g_bpData[nNum].byData = byTemp;
    g_bpData[nNum].nCount = 0;

    byTemp = 0xcc;
    bOK = WriteProcessMemory(hProcess, lpAddr, &byTemp, 1, NULL);
End:
    VirtualProtectEx(hProcess, lpAddr, 1, dwOldProt, &dwNewProt);
    return bOK;
}

BOOL RemoveBreakPoint(HANDLE hProcess, UINT nNum)
{
    if (nNum >= sizeof(g_bpData) / sizeof(BPDATA)) return FALSE;

    BYTE byTemp;
    DWORD dwNewProt, dwOldProt;
    LPVOID lpAddr = g_bpData[nNum].lpAddr;

    VirtualProtectEx(hProcess, lpAddr, 1, PAGE_EXECUTE_READWRITE, &dwOldProt);
    BOOL bOK = ReadProcessMemory(hProcess, lpAddr, &byTemp, 1, NULL);
    bOK = (byTemp == 0xcc);
    if (!bOK) goto End;

    bOK = WriteProcessMemory(hProcess, lpAddr, &g_bpData[nNum].byData, 1, NULL);
    if (bOK) ZeroMemory(g_bpData + nNum, sizeof(BPDATA));
End:
    VirtualProtectEx(hProcess, lpAddr, 1, dwOldProt, &dwNewProt);
    return bOK;
}

BOOL GetDllName(HANDLE hProcess, LPLOAD_DLL_DEBUG_INFO lddi, LPSTR dll_name, int nSize)
{
    LPVOID ptr = 0;
    ReadProcessMemory(hProcess, lddi->lpImageName, &ptr, sizeof(ptr), NULL);
    if( ptr == 0 ) return FALSE;

    WCHAR dll_name_u[MAX_PATH + 1] = {0};
    ReadProcessMemory(hProcess, ptr, dll_name_u, sizeof(dll_name_u), NULL);
    if( dll_name_u[0] == 0 ) return FALSE;

    if( lddi->fUnicode )
        wcstombs(dll_name, dll_name_u, nSize);
    else
        lstrcpyn(dll_name, (LPSTR)dll_name_u, nSize);
    return TRUE;
}


int APIENTRY WinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR    lpCmdLine,
                    int      nCmdShow)
{
    STARTUPINFO si = {0};
    PROCESS_INFORMATION pi = {0};

    // Start the child process.
    if( !CreateProcess( NULL, // No module name (use command line).
        //"D:\\Program Files\\Lantalk XP\\LanTalk.exe", // Command line.
        "LanTalk.exe",    // Command line.
        NULL,            // Process handle not inheritable.
        NULL,            // Thread handle not inheritable.
        TRUE,            // Set handle inheritance to FALSE.
        DEBUG_ONLY_THIS_PROCESS, // creation flags.
        NULL,            // Use parent's environment block.
        //"D:\\Program Files\\Lantalk XP\\",
        NULL,            // Use parent's starting directory.
        &si,              // Pointer to STARTUPINFO structure.
        &pi )            // Pointer to PROCESS_INFORMATION structure.
    )
    {
        MessageBox(NULL, "CreateProcess failed.", "Error", MB_OK);
        return 0;
    }

    LPVOID lpBase[] = {
        0, // kernel32.GetVersion
        0, // kernel32.GetCommandLineA
        LPBYTE(0x0099f8c0), // get clsid string
        0, // advapi32.RegCreateKeyExA
        LPBYTE(0x00402255), // jnz xxx (75 15) --- change to jmp xxx (eb 15)
    };
    // 設定前兩個斷點的目的是為了跳過ASProtect 1.2x的解密過程,
    // 第三個斷點獲得登錄檔鍵值
    // 最後一個斷點作了一個記憶體補丁

    HMODULE hModule = LoadLibrary("kernel32.dll");
    lpBase[0] = GetProcAddress(hModule, "GetVersion");
    lpBase[1] = GetProcAddress(hModule, "GetCommandLineA");
    FreeLibrary(hModule);
    hModule = LoadLibrary("advapi32.dll");
    lpBase[3] = GetProcAddress(hModule, "RegCreateKeyExA");
    FreeLibrary(hModule);

    DEBUG_EVENT dbg = {0};
    CONTEXT context = {0};

    while (WaitForDebugEvent(&dbg, INFINITE))
    {
        if (dbg.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT)
        {
            char dll_name[MAX_PATH] = {0};
            if (GetDllName(pi.hProcess, &dbg.u.LoadDll, dll_name, sizeof(dll_name)))
            {
                if (*dll_name)
                {
                    char *p = strrchr(dll_name, '\\');
                    if (p && lstrcmpi(p + 1, "kernel32.dll") == 0)
                        SetBreakPoint(pi.hProcess, lpBase[0], 0);
                }
            }
        }
        else if (dbg.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
        {
            if (dbg.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
            {
                LPVOID lpAddr = dbg.u.Exception.ExceptionRecord.ExceptionAddress;
                if (lpAddr == lpBase[0] || lpAddr == lpBase[1])
                {
                    context.ContextFlags = CONTEXT_CONTROL;
                    if (GetThreadContext(pi.hThread, &context))
                    {
                        RemoveBreakPoint(pi.hProcess, 0);
                        context.Eip--;
                        SetThreadContext(pi.hThread, &context);
                        if (lpAddr == lpBase[0])
                            SetBreakPoint(pi.hProcess, lpBase[1], 0);
                        else
                            SetBreakPoint(pi.hProcess, lpBase[2], 1);
                    }
                }
                else if (lpAddr == lpBase[2])
                {
                    context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
                    if (GetThreadContext(pi.hThread, &context))
                    {
                        RemoveBreakPoint(pi.hProcess, 1);
                        context.Eip--;
                        SetThreadContext(pi.hThread, &context);
                        LPVOID ptr = NULL;
                        if (ReadProcessMemory(pi.hProcess, (LPVOID)context.Ebx, &ptr, sizeof(ptr), NULL))
                        {
                            char szClsid[45] = {0};
                            if (ReadProcessMemory(pi.hProcess, ptr, szClsid, sizeof(szClsid), NULL))
                                SHDeleteKey(HKEY_CLASSES_ROOT, szClsid);
                        }
                        SetBreakPoint(pi.hProcess, lpBase[3], 0);
                    }
                }
                else if (lpAddr == lpBase[3])
                {
                    context.ContextFlags = CONTEXT_CONTROL;
                    if (GetThreadContext(pi.hThread, &context))
                    {
                        RemoveBreakPoint(pi.hProcess, 0);
                        context.Eip--;
                        SetThreadContext(pi.hThread, &context);
                        DWORD dwTemp = 0;
                        ReadProcessMemory(pi.hProcess, lpBase[4], &dwTemp, 4, NULL);
                        if (dwTemp == 0xbe391575)
                        {
                            dwTemp = 0xeb;
                            WriteProcessMemory(pi.hProcess, lpBase[4], &dwTemp, 1, NULL);
                        }
                    }
                }
                ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, DBG_CONTINUE);
            }
        }
        else if (dbg.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
            break;
        ContinueDebugEvent(dbg.dwProcessId, dbg.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
    }

    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    return 0;
}

相關文章