microsoft / Detours

Detours is a software package for monitoring and instrumenting API calls on Windows. It is distributed in source code form.
MIT License
5.29k stars 1.02k forks source link

Can I call a function from Exe in the injected function of the dll ? #319

Open wdw753951 opened 4 months ago

wdw753951 commented 4 months ago

I am new to learn the hook, I have a question For example I know the address

typedef DWORD(*calcTextCharLengh_type)(char*, DWORD*);

myfun is my hook function
void myfun(){

    calcTextCharLengh_type calcTextCharLength = reinterpret_cast<calcTextCharLengh_type>(0x410C20);
    calcTextCharLength(xxx,xxx);
}

//when hook Successfully,the exe crash in this call, how can I call the exe's function

sylveon commented 4 months ago

This is most likely crashing because of ASLR. You should be able to call the function (assuming your signature is correct) once you find the address of the function you want (most likely doing GetModuleHandle(nullptr) + some_offset)

wdw753951 commented 4 months ago

This is most likely crashing because of ASLR. You should be able to call the function (assuming your signature is correct) once you find the address of the function you want (most likely doing GetModuleHandle(nullptr) + some_offset)

This is my dll program it hook sucessfully ,if i don't call the function of 0x410C20 ,it works perfectly !!the exe is an old game , i see the address of 0x410C20 is fixed in the 'x64dbg' ,the address of 0x410c20 is a function to calculate the length of a japanese char according to the assembly code in the x64dbg

#include "pch.h"
#include<Windows.h>
#include<stdio.h>
#include <detours.h>
#include <stdint.h>

struct MessageInfo {
    int32_t unkonw_0;
    HDC * hdc_address;
    int32_t unkonw_2;
    int32_t unkonw_3;
    int32_t unkonw_4;
    uchar * message_addr;
    int32_t length;
    int32_t total_length;
    int32_t left_top_start_x;
    int32_t left_top_start_y;
    int32_t current_text_left_top_x;
    int32_t current_text_left_top_y;
    int32_t unkonw_12;
};

void (*OldDrawText)(DWORD, DWORD , DWORD) = (void(*)(DWORD, DWORD, DWORD))0x410AD0;
bool(*OldDrawTextPerTime)(DWORD, DWORD, DWORD) = (bool(*)(DWORD, DWORD, DWORD))0x410A10;
//DWORD(*calcTextCharLengh)(char*, DWORD*) = (DWORD(*)(char*, DWORD*))0x410C20;
typedef DWORD(*calcTextCharLengh_type)(char*, DWORD*);

void WINAPI MyFunction0(DWORD a, DWORD b, DWORD c)
{
    MessageInfo *info = (MessageInfo *)b;
    HDC *hdc = info->hdc_address;
    HFONT hFont = CreateFontA(
        24, 
        0, 
        0,
        0, 
        FW_NORMAL, 
        FALSE, 
        FALSE,
        FALSE, 
        SHIFTJIS_CHARSET, 
        OUT_DEFAULT_PRECIS,
        CLIP_DEFAULT_PRECIS,
        DEFAULT_QUALITY,
        FF_ROMAN | TMPF_TRUETYPE ,
        "MS ゴシック"
    );
    SelectObject(*hdc, hFont);
    SetTextColor(*hdc, 0xFFFFFF);
    HMODULE user32_module = GetModuleHandleA("user32.dll");
    FARPROC drawText = GetProcAddress(user32_module, "DrawTextA");
    typedef int(WINAPI* LPDrawTextA)(HDC, LPCSTR, int, LPRECT, UINT);
    LPDrawTextA pDrawTextA = reinterpret_cast<LPDrawTextA>(drawText); 
    //TextOutA(*hdc, 10, 10, info->message_addr, info->total_length);
    RECT rect = {
        info->left_top_start_x,info->left_top_start_y,602,460
    };
    pDrawTextA(*hdc, info->message_addr, info->total_length, &rect, 0x14);
    info->length = info->total_length;
    info->unkonw_12 = 1;
    __asm {
        pop edi;
        pop esi;
        mov esp, ebp
        pop ebp;
        ret
    }

    return;
}

bool WINAPI drawFunnctionPerTime(DWORD a, DWORD b, DWORD c) {
    MessageInfo *info = (MessageInfo *)b;
    HDC *hdc = info->hdc_address;
    HFONT hFont = CreateFontA(
        24, 
        0, 
        0, 
        0, 
        FW_NORMAL, 
        FALSE, 
        FALSE, 
        FALSE, 
        SHIFTJIS_CHARSET, 
        OUT_DEFAULT_PRECIS, 
        CLIP_DEFAULT_PRECIS, 
        DEFAULT_QUALITY, 
        FF_ROMAN | TMPF_TRUETYPE,
        "MS ゴシック" 
    );
    SelectObject(*hdc, hFont);
    SetTextColor(*hdc, 0xFFFFFF);
    HMODULE user32_module = GetModuleHandleA("user32.dll");
    FARPROC drawText = GetProcAddress(user32_module, "DrawTextA");
    typedef int(WINAPI* LPDrawTextA)(HDC, LPCSTR, int, LPRECT, UINT);
    LPDrawTextA pDrawTextA = reinterpret_cast<LPDrawTextA>(drawText); 
    //TextOutA(*hdc, 10, 10, info->message_addr, info->total_length);

    if (*(char *)(info->message_addr + info->length) == 10)
    {
        info->current_text_left_top_x = info->left_top_start_x;
        int temp_y = info->current_text_left_top_y;
        info->current_text_left_top_y = temp_y + 24;
        info->length++;
    }
    else {
        DWORD temp[2];

        calcTextCharLengh_type calc_text_char = reinterpret_cast<calcTextCharLengh_type>(0x410C20);

        //int32_t code_length = calc_text_char(info->message_addr + info->length, temp);

        int32_t code_length = 2;
        RECT rect = {
            info->current_text_left_top_x,
            info->current_text_left_top_y,
            602,
            460
        };
        pDrawTextA(*hdc, info->message_addr + info->length, code_length, &rect, 0x14);
        info->current_text_left_top_x += 12 * code_length;
        info->length += code_length;
    }

    DWORD result;
    if (info->length == info->total_length) {
        info->unkonw_12 = 1;
        result = true;
    }
    else {
        info->unkonw_12 = 0;
        result = false;
    }
    __asm{
        cmp edx, ecx
        pop edi
        pop esi
        sete al
        pop ebx
        mov esp, ebp
        pop ebp
    ret 0
    }
    return result;

}

DWORD WINAPI ThreadProc()
{

    DetourTransactionBegin();

    DetourUpdateThread(GetCurrentThread());

    DetourAttach(&(PVOID&)OldDrawText, MyFunction0);
    DetourAttach(&(PVOID&)OldDrawTextPerTime, drawFunnctionPerTime);

    DetourTransactionCommit();

    return 0;
};

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH: {
        ThreadProc();
        //HANDLE hThread = CreateThread(NULL, 0, ThreadProc, (LPVOID)NULL, 0, NULL);
        break;
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
wdw753951 commented 4 months ago

This is most likely crashing because of ASLR. You should be able to call the function (assuming your signature is correct) once you find the address of the function you want (most likely doing GetModuleHandle(nullptr) + some_offset) I am sorry ,thank you very much, it can call the function 410c20 but why the assembly code is like this , there is no push parameter before call this functin so when i step in this function ,it crashed when it use the stack of esp image

weltkante commented 4 months ago

there is no push parameter before call this functin

maybe its the wrong calling convention you're using in the source code?

set the compiler to output assembly for your source file and compare how it looks vs. the way its called in the original assembly code

wdw753951 commented 4 months ago

this is the orgin call,two para in esp+4 and esp+8 image

this is the dll call ,no para in the stack image

wdw753951 commented 4 months ago

This is most likely crashing because of ASLR. You should be able to call the function (assuming your signature is correct) once you find the address of the function you want (most likely doing GetModuleHandle(nullptr) + some_offset)

thank you this is my falut I use _fastcall /gr case this problem

i change to the convention ,beacause i have a probem before i do not need ret C ,I only need ret 0 ,i dont know how to modify this, at last i write the asm in my source code image