30-07-2025, 04:08 AM
fasm x64 assembly specializes in solving TOTALCMD64 11.51 not loading msimg32.dll
format PE64 GUI 5.0
entry start
include 'win64a.inc'
; Constant definition
INFINITE = 0xFFFFFFFF
MEM_COMMIT = 0x1000
MEM_RESERVE = 0x2000
PAGE_READWRITE = 0x04
CREATE_SUSPENDED = 0x00000004
section '.data' data readable writeable
my_dll_path db 'msimg32.dll',0
my_dll_path_len = $ - my_dll_path ; string length (including NULL)
process_info PROCESS_INFORMATION
startup_info STARTUPINFO
process_handle dq ?
process_id dd ?
thread_handle dq ?
kernel32_dll db 'kernel32.dll',0
load_library_name db 'LoadLibraryA',0
load_library_addr dq ?
remote_mem dq ?
thread_ret dq ? ; Remote thread handle
section '.code' code readable executable
start:
sub rsp, 8 ; align stack
; Initialize the STARTUPINFO structure
is rdi, [startup_info]
mov rcx, sizeof.STARTUPINFO
xor eax, eax
rep stosb
mov [startup_info.cb], sizeof.STARTUPINFO
; Create a suspended Notecase.exe process
invoke CreateProcessA, 0, "TOTALCMD64.EXE", 0, 0, 0, \
CREATE_SUSPENDED, 0, 0, startup_info, process_info
test rax, rax
jz exit_program
; Save process handle and PID
mov rax, [process_info.hProcess]
mov [process_handle], rax
mov eax, [process_info.dwProcessId]
mov [process_id], eax
; Save thread handle
mov rax, [process_info.hThread]
mov [thread_handle], rax
; Get the address of LoadLibraryA
invoke GetModuleHandleA, kernel32_dll
test rax, rax
jz exit_program_cleanup
invoke GetProcAddress, rax, load_library_name
test rax, rax
jz exit_program_cleanup
mov [load_library_addr], rax
; Allocate memory in the target process
invoke VirtualAllocEx, [process_handle], 0, my_dll_path_len, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE
test rax, rax
jz exit_program_cleanup
mov [remote_mem], rax
; Write DLL path
invoke WriteProcessMemory, [process_handle], [remote_mem], my_dll_path, my_dll_path_len, 0
test rax, rax
jz exit_program_cleanup
; Create a remote thread to call LoadLibraryA
invoke CreateRemoteThread, [process_handle], 0, 0, [load_library_addr], [remote_mem], 0, 0
test rax, rax
jz exit_program_cleanup
mov [thread_ret], rax ; save remote thread handle
; Wait for DLL to load
invoke WaitForSingleObject, [thread_ret], INFINITE
; Check if the DLL was loaded successfully (optional)
invoke GetExitCodeThread, [thread_ret], remote_mem
test rax, rax
jz @f
cmp [remote_mem], 0
jnz @f
; You can handle the situation where DLL loading fails here
@@:
; Close the remote thread handle
invoke CloseHandle, [thread_ret]
; Restore the main thread of notecase.exe (critical repair point!)
invoke ResumeThread, [thread_handle]
exit_program_cleanup:
; Release the allocated memory
invoke VirtualFreeEx, [process_handle], [remote_mem], 0, MEM_RELEASE
; Close the handle
invoke CloseHandle, [thread_handle]
invoke CloseHandle, [process_handle]
exit_program:
invoke ExitProcess, 0
section '.idata' import data readable writeable
library kernel32, 'kernel32.dll'
include 'api\kernel32.inc'
LEARNING