Как вызвать оригинальную функцию после отцепления? - PullRequest
0 голосов
/ 03 февраля 2019

Я подключаю функцию LdrLoadDll() и добился успеха.Теперь я хочу внести небольшое изменение в код, чтобы, когда нет определенной загрузки DLL, вызвать оригинальную функцию.

Я попробовал следующую реализацию, но приложение вылетает при вызове исходной функции.

  • Сначала я отсоединяю API
  • После этого я присваиваю переменной переменную прототип 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())
                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);
}
...