rust dll load 과정 기록

wangki·2025년 4월 9일
0

Rust

목록 보기
32/54

rust dll code

use hooking_api::utils::{get_filename_by_module, get_module_list};

use windows::{core::PCSTR, Win32::{Foundation::*, System::{SystemServices::*, Threading::GetCurrentProcess}, UI::WindowsAndMessaging::{MessageBoxA, MB_OK}}};
use windows::Win32::System::Diagnostics::Debug::OutputDebugStringA;

#[unsafe(no_mangle)]
#[allow(non_snake_case, unused_variables)]
pub extern "system" fn DllMain(dll_module: HINSTANCE, fdw_reason: u32, _: *mut ()) -> bool {
    match fdw_reason {
        DLL_PROCESS_ATTACH => {  // DLL_PROCESS_ATTACH
            test_func();
        }
        DLL_PROCESS_DETACH => {
            
        }
        _ => {
        
        }
    }
    true
}

pub fn test_func() {
    let vec = get_module_list(None).unwrap();
    unsafe {
        let handle = GetCurrentProcess();
        for module in vec {
            let moduel_name = get_filename_by_module(handle, module).unwrap();
            let debug_str = format!("[hook_test] {}", moduel_name);
            OutputDebugStringA(PCSTR(debug_str.as_ptr()));
        }
    }
}

hooking_api을 통해 iat hooking을 테스트하기 전, 모듈이 정상적으로 로드되어 동작을 하는지 확인하는 과정을 기록하겠다.

// cargo.toml
[lib]
crate-type = ["cdylib"]

[dependencies]
hooking_api = { path = "C:/Users/PC/Downloads/hooking_api"}


[dependencies.windows]
version = "*"
features = [
    "Win32_Foundation",
    "Win32_System_SystemServices",
    "Win32_UI_WindowsAndMessaging",
    "Win32_System_Diagnostics_Debug",
]

위와 같이 cargo.toml파일을 설정 후 빌드하게되면 dll파일을 얻을 수 있다.

cpp 모듈 로드 코드

cpp코드에서

int main()
{
	Sleep(INFINITE);

    HMODULE module = LoadLibraryA("d:\\work\\rust\\test\\test_20250409\\target\\debug\\test_20250409.dll");
	if (module == NULL) {
		std::cerr << "Failed to load the DLL" << std::endl;
		return 1;
	}

	Sleep(INFINITE);

	FreeLibrary(module);

	std::cout << "Hello World!\n";
	return 0;
}

이렇게 로드하게 되면 load시킨 dll의 dllmain이 실행된다.

pub fn test_func() {
    let vec = get_module_list(None).unwrap();
    unsafe {
        let handle = GetCurrentProcess();
        for module in vec {
            let moduel_name = get_filename_by_module(handle, module).unwrap();
            let debug_str = format!("[hook_test] {}", moduel_name);
            OutputDebugStringA(PCSTR(debug_str.as_ptr()));
        }
    }
}

모듈 확인

test_funcDLL_PROCESS_ATTACH시 호출하는데 현재 프로세스에 로드된 모듈을 모두 가져온다.

OutputDebugStringA으로 디버그 출력을 하므로 DbgView
로 확익할 수 있다.

현재 ConsoleApplication.exe에 로드된 모듈을 볼 수 있다. 그러면 실제로 debug 출력된 모듈이 맞는지 확인을 해야한다.

최애 프로그램 WinDBG를 통해 확인하겠다.
로드 후 sleep을 통해서 강제로 프로그램을 멈추도록 했다.
디버거를 Attach 시킨 후 lm명령어를 통해 현재 로드된 모듈을 확인했다.

그리고 눈으로 확인했지만 ai의 발전으로 가볍게 복사 후 비교해달라고 요청하였다.

깔끔히 정리가 되었다.
따라서 개발한 프로그램이 의도대로 동작을 하였다.

iat 후킹을 구현하도록 해야겠다.

0개의 댓글