#1
|
|||
|
|||
help for create loader with packed program
hi
I have a plan and I want to write a loader for it Because the packed program takes a while to load in memory I wanted to see how to load loaders for such programs I will send an example that uses the following functions to load the desired part in memory and then start patching Function: CreateToolhelp32Snapshot Process32FirstW Process32NextW OpenProcess Module32FirstW ReadProcessMemory VirtualProtectEx WriteProcessMemory |
The Following User Says Thank You to mcr4ck For This Useful Post: | ||
niculaita (02-05-2021) |
#2
|
|||
|
|||
please help
|
#3
|
|||
|
|||
Use advanced loader generator,if i remember have options like sleep and wait until first windows before apply the patches,the final loader is a VB6 packed with upx,just unpack it and you can check how works.
Here a very good basic example made by Xylitol https://github.com/Xyl2k/Xylitol-MAS...der)/patch.asm Last edited by Top10; 02-03-2021 at 06:08. |
#4
|
|||
|
|||
long ago when I was learning programming I wrote a simple library for patching memory on the fly.
It supports Wait till first window of process and wait until some fixed bytes are decrypted in memory. I should full fill your requirements https://github.com/GautamGreat/LoaderEngine |
#5
|
|||
|
|||
Below is an example of a loader using the Cheat Engine that I found on the net.
<?xml version="1.0" encoding="utf-8"?> <CheatTable CheatEngineTableVersion="31"> <CheatEntries/> <UserdefinedSymbols/> <LuaScript>PROCESS_NAME = 'GDAE3.86.pro.exe' -------- -------- Auto Attach -------- local autoAttachTimer = nil ---- variable to hold timer object local autoAttachTimerInterval = 1000 ---- Timer intervals are in milliseconds local autoAttachTimerTicks = 0 ---- variable to count number of times the timer has run local autoAttachTimerTickMax = 5000 ---- Set to zero to disable ticks max local function autoAttachTimer_tick(timer) ---- Timer tick call back ---- Destroy timer if max ticks is reached if autoAttachTimerTickMax > 0 and autoAttachTimerTicks >= autoAttachTimerTickMax then timer.destroy() end ---- Check if process is running if getProcessIDFromProcessName(PROCESS_NAME) ~= nil then timer.destroy() ---- Destroy timer openProcess(PROCESS_NAME) ---- Open the process writeBytes(0x00458816, 0xb8, 0x01, 0x00, 0x00, 0x00 ) writeBytes(0x00448120, 0xc7, 0x83, 0x70, 0x09, 0x00, 0x00, 0x01, 0x00, 0x00) writeBytes(0x0044812A, 0xe9, 0x9c, 0x00, 0x00, 0x00, 0x90, 0x90 ) writeBytes(0x004485E6, 0xeb) writeBytes(0x00443973, 0xeb) ---pause() end autoAttachTimerTicks = autoAttachTimerTicks + 1 ---- Increase ticks end autoAttachTimer = createTimer(getMainForm()) ---- Create timer with the main form as it's parent autoAttachTimer.Interval = autoAttachTimerInterval ---- Set timer interval autoAttachTimer.OnTimer = autoAttachTimer_tick ---- Set timer tick call back </LuaScript> </CheatTable> I hope you find it useful. |
The Following 4 Users Say Thank You to LordGarfio For This Useful Post: | ||
mcr4ck (02-04-2021), niculaita (07-22-2021), Sailor_EDA (07-28-2021), sh3dow (07-26-2021) |
#6
|
|||
|
|||
Patching by Hooking
If the target has more than one protection layer, you need to patch them in order. Try to hook to WINAPI which is being used by program during unpacking (HeapAlloc, VirtualAlloc, CreateFile ...)
Below sample uses ms detours to hook to DeviceIOControl to check the memory of target. When memory compare is equal, then patching first layer. If you need to more patching after first layer unpacking, you have to continue to check the memory of program. After final patching, you can detach DeviceIOControl. Code:
// dllmain.cpp : Defines the entry point for the DLL application. #include "pch.h" #include <iostream> #include <vector> #include <Windows.h> #include <tlhelp32.h> #include "detours.h" #pragma comment(lib, "detours.lib") using namespace std; BOOL WINAPI My_DeviceIoControl( HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped ); static BOOL(WINAPI* Ori_DeviceIoControl) ( HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped ) = NULL; BYTE bytes_written_1[] = { 0x33, 0xC0, 0xC2, 0x0C, 0x00, 0x90 }; BYTE bytes_written_2[] = { 0x33, 0xC0, 0xC2, 0x0C, 0x00, 0x90x 0x90 }; DWORD GetProcId(const wchar_t* procName) { DWORD procId = 0; HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnap != INVALID_HANDLE_VALUE) { PROCESSENTRY32 procEntry; procEntry.dwSize = sizeof(procEntry); if (Process32First(hSnap, &procEntry)) { do { if (!_wcsicmp(procEntry.szExeFile, procName)) { procId = procEntry.th32ProcessID; break; } } while (Process32Next(hSnap, &procEntry)); } } CloseHandle(hSnap); return procId; } DWORD GetModuleBaseAddress(DWORD procId, const wchar_t* modName) { DWORD modBaseAddr = 0; HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId); if (hSnap != INVALID_HANDLE_VALUE) { MODULEENTRY32 modEntry; modEntry.dwSize = sizeof(modEntry); if (Module32First(hSnap, &modEntry)) { do { if (!_wcsicmp(modEntry.szModule, modName)) { modBaseAddr = (DWORD)modEntry.modBaseAddr; break; } } while (Module32Next(hSnap, &modEntry)); } } CloseHandle(hSnap); return modBaseAddr; } BOOL APIENTRY DllMain(HMODULE hDLL, DWORD ul_reason_for_call, LPVOID lpReserved ) { HMODULE dll_module_1 = GetModuleHandleA("kernel32.dll"); if (!dll_module_1) { DWORD dw = GetLastError(); MessageBox(NULL, L"The library could not load", L"ERROR", MB_OK); } { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: DetourRestoreAfterWith(); Ori_DeviceIoControl = (BOOL(WINAPI*) (HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPOVERLAPPED)) DetourFindFunction("kernel32.dll", "DeviceIoControl"); DisableThreadLibraryCalls(hDLL); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)Ori_DeviceIoControl, My_DeviceIoControl); if (DetourTransactionCommit() != NO_ERROR) MessageBox(NULL, L"Detour Attach Error", NULL, MB_OK); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)Ori_DeviceIoControl, My_DeviceIoControl); DetourTransactionCommit(); break; } return TRUE; } } BOOL WINAPI My_DeviceIoControl( HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped ) { DWORD processID = GetProcId(L"??????.exe"); HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, processID); DWORD moduleBase = GetModuleBaseAddress(processID, L"?????.exe"); if (moduleBase != 0) { DWORD target_adres = moduleBase + ??????; DWORD* target_adres_ = 0; DWORD dwLen_ = 0; BOOL sonuc = false; DWORD* control_1 = (DWORD*)0x0???????; DWORD* control_2 = (DWORD*)0x0???????; DWORD oldprotect; if (target_adres != 0) { ReadProcessMemory(hProcess, (LPVOID)target_adres, (LPVOID)&target_adres_, 4, NULL); if (target_adres_ == control_1) { unsigned int length_ = 6; VirtualProtectEx(hProcess, (LPVOID)target_adres, length_, PAGE_EXECUTE_READWRITE, &oldprotect); sonuc = WriteProcessMemory(hProcess, (LPVOID)target_adres, &bytes_written_1, length_, &dwLen_); // 1st patch (1st Layer) VirtualProtectEx(hProcess, (LPVOID)target_adres, length_, oldprotect, &oldprotect); ... ... if (sonuc) { //MessageBox(NULL, L"patched", NULL, MB_OK); // 1st layer is OK, patched } } } target_adres = moduleBase + 0x0???; // 2nd layer (if needed) if (target_adres != 0) { ReadProcessMemory(hProcess, (LPVOID)target_adres, (LPVOID)&target_adres_, 4, NULL); if (target_adres_ == control_2) { unsigned int length_= 7; VirtualProtectEx(hProcess, (LPVOID)hedef_adres, uzunluk, PAGE_EXECUTE_READWRITE, &oldprotect); sonuc = WriteProcessMemory(hProcess, (LPVOID)hedef_adres, &bytes_written_4, uzunluk, &dwLen_); // 2nd patch (2nd layer) VirtualProtectEx(hProcess, (LPVOID)hedef_adres, uzunluk, oldprotect, &oldprotect); ... ... DetourTransactionBegin(); // JOB is done, it is time to Detach DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)Ori_DeviceIoControl, My_DeviceIoControl); DetourTransactionCommit(); } } } BOOL fake_handle = false; fake_handle = Ori_DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped); return fake_handle; } |
The Following 5 Users Say Thank You to raduga_fb For This Useful Post: | ||
countryboy (09-22-2021), mcr4ck (02-04-2021), niculaita (07-22-2021), sh3dow (07-26-2021), user1 (07-31-2021) |
#7
|
||||
|
||||
Quote:
This is my Loader in Delphi Program (Some function in my programing library but i think you understand) Code:
function Loader_PEFile(FName: string; FCRC32: string; pbyte: array of Byte; paddr: array of Cardinal; pSize: DWord): Boolean; var StartupInfo: TStartupInfo; ProcessInfo: TProcessInformation; i,BytesRead: Cardinal; Buffer: array[0..4095] of Byte; begin Result:= False; FillChar(Buffer,psize+1, 0); FillMeMory(@StartupInfo, SizeOf(StartupInfo), 0); StartupInfo.cb:= SizeOf(StartupInfo); if CreateProcessA(PChar(FName), nil, nil, nil, FALSE, NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then begin WaitForInputIdle(ProcessInfo.hProcess, 2000); //INFINITE SuspendThread(ProcessInfo.hThread); if GetFileCRC32(FName) <> FCRC32 then begin TerminateProcess(ProcessInfo.hProcess, 0); MessageBox(0, PChar(ExtractFileName(FName) + ' - Loader is fail!' +#10+ { - Loader is fail!} 'File was patched or other version.'), PChar('WARNING'), 48); end else begin if (psize = 1) OR (psize = 0)then begin for i:= 0 to SizeOf(pbyte)-1 do begin VirtualProtectEx(ProcessInfo.hProcess,Ptr(paddr[i]),psize,PAGE_EXECUTE_READWRITE,BytesRead); ReadProcessMemory(ProcessInfo.hProcess,Ptr(paddr[i]),@Buffer[i],psize,BytesRead); WriteProcessMemory(ProcessInfo.hProcess,Ptr(paddr[i]),@pbyte[i],psize,BytesRead); end; end else begin VirtualProtectEx(ProcessInfo.hProcess,Ptr(paddr[0]),psize,PAGE_EXECUTE_READWRITE,BytesRead); ReadProcessMemory(ProcessInfo.hProcess,Ptr(paddr[0]),@Buffer,psize,BytesRead); WriteProcessMemory(ProcessInfo.hProcess,Ptr(paddr[0]),@pbyte,psize,BytesRead); end; Sleep(200); ResumeThread(ProcessInfo.hThread); Result:= True; end; end else MessageBox(0, PChar(ExtractFileName(FName) + 'FName not found in current dir'), PChar('WARNING'), 48); end; quygia128 |
The Following 4 Users Say Thank You to quygia128 For This Useful Post: | ||
countryboy (09-22-2021), mcr4ck (02-04-2021), niculaita (07-22-2021), sh3dow (07-26-2021) |
#8
|
|||
|
|||
Quote:
pch.h detours.h and Programming IDE and compiler thanks |
The Following User Says Thank You to mcr4ck For This Useful Post: | ||
countryboy (09-22-2021) |
#9
|
|||
|
|||
how do use this
https://github.com/GautamGreat/LoaderEngine please example |
The Following User Says Thank You to mcr4ck For This Useful Post: | ||
niculaita (07-22-2021) |
#10
|
|||
|
|||
Quote:
Code:
program Project1; {$APPTYPE GUI} uses Winapi.Windows, System.SysUtils, Loader_Engine in '..\..\..\..\..\Coding-and-Programming\Delphi_Projects\Loader_Engine.pas'; const patchAddrRVA = $05234536; var patchAsm : array[0..24] of Byte = ($9C, $52, $89, $2C, $24, $3E, $8B, $44, $24, $F4, $8B, $00, $C6, $00, $01, $B8, $FF, $FF, $FF, $FF, $E9, $00, $00, $00, $00); lE : TLoaderEngine; newMem : Pointer; patchAddr : DWORD; jmp_byte : Byte = $E9; jmp_write : DWORD; function jmpCalc(src, dst : DWORD) : DWORD; begin Result := dst - src - 5; end; begin try lE := TLoaderEngine.Create('test_program.exe', True, False); try if lE.WaitTillFirstWindow(1000) then begin lE.SuspendPThread; newMem := le.AllocMemory($1000); patchAddr := patchAddrRVA + lE.GetModuleBaseAddress; jmp_write := jmpCalc(patchAddr, DWORD(newMem)); lE.WriteMemory(DWORD(newMem), patchAsm[0], Length(patchAsm)); lE.WriteMemory(patchAddr, jmp_byte, 1); lE.WriteMemory(patchAddr+1, jmp_write, 4); jmp_write := jmpCalc(DWORD(newMem)+$14, patchAddr+5); lE.WriteMemory(DWORD(newMem)+$15, jmp_write, 4); lE.ResumePThread; end else MessageBox(0, 'Failed to detect Windows', 'Error', MB_ICONERROR); finally lE.Destroy; end; except on E:exception do MessageBox(0, PChar(E.Message), PChar(E.ClassName), MB_ICONERROR); end; end. |
The Following 2 Users Say Thank You to GautamGreat For This Useful Post: | ||
countryboy (09-22-2021), niculaita (02-06-2021) |
#11
|
|||
|
|||
Please send the following files as well
pch.h detours.h and Programming IDE and compiler thanks |
The Following User Says Thank You to mcr4ck For This Useful Post: | ||
niculaita (02-06-2021) |
#12
|
|||
|
|||
Quote:
|
The Following 3 Users Say Thank You to mcr4ck For This Useful Post: | ||
#14
|
|||
|
|||
I will compile in visual studio 2012
But he made a mistake error C1083: Cannot open include file: 'pch.h': No such file or directory plz help for compile thanks |
The Following User Says Thank You to mcr4ck For This Useful Post: | ||
countryboy (09-22-2021) |
#15
|
|||
|
|||
comment it out and configure your project not to use precompiled headers
hope this helps |
The Following 2 Users Say Thank You to xobor For This Useful Post: | ||
countryboy (09-22-2021), niculaita (07-30-2021) |
Thread Tools | |
Display Modes | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
dot net - how to create keygen using program's code | Maltese | General Discussion | 5 | 06-15-2011 09:02 |