Overview
Penelitian ini berkembang dari laboratorium MinHook sederhana menjadi lingkungan diagnostic Windows x86/x64 untuk memetakan module, state internal, hash generation, komunikasi WinINet, response normalization, dan decision path pada sebuah target Point Blank yang diuji secara terkontrol.
Instrumentation target-specific menggunakan model observe/delegate: detour merekam argument dan state, memanggil original function melalui trampoline, mencatat hasil original, lalu mengembalikan hasil tersebut tanpa mengubah keputusan native program.
Evolusi project
Implementasi awal hanya menguji hook pada exported function sederhana. Setelah itu project berkembang menjadi pipeline diagnostic yang mencakup:
- build MinHook x86 dan x64;
- controlled exported-function hook;
- process dan module enumeration;
- remote diagnostic DLL loading untuk test terkontrol;
- diagnostic injector x86;
- pemilihan target module dengan SHA-256;
- signature-based payload discovery;
- runtime logging ke
%TEMP%\dll_minhook.log; - executable-section xref scanning terhadap global state;
- state-generation tracing;
- ABI-correct hook untuk MD5 wrapper x86;
- WinINet request/response tracing;
- lazy comparator tracing.
Black-box observation pipeline
locate correct module
|
v
load diagnostic DLL
|
v
retain analyzed payload
|
v
locate important state
|
v
trace state generation
|
v
trace network transport
|
v
trace normalized response
|
v
trace final comparison
Model ini lebih berguna daripada hanya memeriksa satu conditional branch karena seluruh hubungan antar-state dapat dikorelasikan dalam satu timeline runtime.
Pemilihan target module berbasis SHA-256
Nama DLL payload dapat berubah, sehingga pemilihan berdasarkan filename tidak cukup stabil. Diagnostic launcher kemudian menggunakan SHA-256 sebagai identitas target module.
Secara konseptual launcher melakukan:
enumerate matching process
|
v
enumerate loaded modules
|
v
map candidate read-only
|
v
SHA-256 with Windows CNG
|
v
compare expected digest
|
v
retain matching target
Pendekatan ini memisahkan random filename dari kontrak diagnostic dan membuat pemilihan payload lebih repeatable.
Target retention dan initialization
Setelah diagnostic DLL aktif, target payload dipertahankan sebagai module base untuk seluruh tracer. Setup berat tidak dijalankan langsung di bawah loader lock; DllMain membuat worker thread yang kemudian menjalankan initialization sequence.
DllMain
└─ worker thread
└─ hooks initialization
├─ logger
├─ MinHook
├─ retain target payload
├─ verifier trace
├─ dispatch trace
└─ response-handler trace
├─ state-reference trace
├─ MD5-call trace
├─ state-generation trace
├─ gate trace
└─ WinINet trace
Global state dan xref scanning
Static analysis mengidentifikasi empat global std::string yang relevan dengan flow runtime. Lokasi relatif pada build yang dianalisis:
stateB RVA 0xD37B8
context39A4 RVA 0xD39A4
context3C50 RVA 0xD3C50
stateA RVA 0xD3C08
Scanner berjalan pada executable PE sections dan mencari encoded absolute address dari global-global tersebut. Setiap reference dicatat bersama section, RVA, surrounding machine-code window, dan reference count.
Salah satu masalah yang ditemukan adalah verifier signature sudah berubah setelah MinHook memasang patch. Resolver kemudian menggunakan signature dari helper lain yang masih original agar target module tetap dapat ditemukan setelah initialization.
State-generation trace
Hook pada helper std::string move-assignment digunakan untuk mengamati write terhadap state terpilih. Event penting adalah write menuju stateA, karena event tersebut menghubungkan hash-generation pipeline dengan global value yang nantinya digunakan oleh response path.
TRACE state-write target=stateA
source_before="..."
destination_after="..."
stateB_before="..."
context39A4="..."
context3C50="..."
caller_rva=...
MD5 wrapper reverse engineering
Static analysis menemukan helper MD5 x86 pada RVA 0x8FF30. Fungsi tersebut menerima value std::string, menjalankan MD5 normal, lalu mengubah digest 16 byte menjadi string lowercase hexadecimal 32 karakter menggunakan formatting %02x.
MD5_HEX(input) -> 32 lowercase hexadecimal characters
ABI caller-clean yang tidak biasa
Calling pattern helper ini penting untuk stability detour:
- destination string object berada di
ECX; - 24-byte
std::stringvalue dikirim melalui stack; - original function berakhir dengan plain
ret; - caller melakukan
add esp, 0x18.
Typed detour konvensional tidak mempertahankan layout tersebut secara aman. Implementasi final menggunakan naked x86 entry shim, representasi POD 24-byte, manual trampoline call, dan preservation terhadap caller-owned stack arguments. Initialization log menandainya sebagai abi=caller-clean-naked-shim.
Runtime hash pipeline
Runtime trace akhirnya menunjukkan tiga MD5 call yang saling berhubungan.
1. Producer stateB
stateB = MD5_HEX(producer_input)
Pada salah satu sesi observasi:
producer_input = 441944720010469927754526196619
stateB = ceb5f92a4b894d33387b969ed6d57ff7
2. stateA stage 1
Program membentuk:
context39A4 = stateB + "aktif" + stateB
hash1 = MD5_HEX(context39A4)
Pada sesi yang sama:
context39A4 = ceb5f92a4b894d33387b969ed6d57ff7aktifceb5f92a4b894d33387b969ed6d57ff7
hash1 = 954c1528c30c9a2107f2e2ce26137ff4
3. stateA stage 2
stateA = MD5_HEX(hash1)
Hasil pada sesi tersebut:
stateA = 4838bf55e43b5a6d3cc76e5effd87d69
Hubungan lengkap yang teramati:
stateB = MD5_HEX(producer_input)
context39A4 = stateB + "aktif" + stateB
hash1 = MD5_HEX(context39A4)
stateA = MD5_HEX(hash1)
Instrumentation runtime juga menyelesaikan satu ambiguity pada verifikasi manual sebelumnya: stage-1 hash yang disalin secara manual sempat kehilangan karakter terakhir sehingga hasil second MD5 tampak tidak cocok.
WinINet request tracing
Network layer yang diamati menggunakan:
InternetOpenA
InternetConnectA
HttpOpenRequestA
HttpSendRequestA
InternetReadFile
Tracer mencatat server, port, HTTP verb, object/path, request result, Win32 error, HTTP status, serta returned bytes dalam ASCII dan hexadecimal.
Runtime trace menunjukkan bahwa outbound GET membawa stateB melalui query parameter k:
...&k=<stateB>
Ini membedakan dua state utama: stateB dikirim melalui request, sedangkan stateA tetap berada lokal untuk digunakan oleh comparison path.
Response normalization
Body dari InternetReadFile tidak langsung menjadi comparator input. Response melewati normalization stage lebih dulu. Karena itu raw HTTP body dan string yang sampai ke comparator dapat berbeda, misalnya karena whitespace yang dihapus.
HTTP response bytes
|
v
application normalization
|
v
normalized_response
Comparator trace
Response-handler akhirnya menuju comparator sekitar RVA 0xC6B0. Hook comparator dipasang secara lazy tepat sebelum response handler berjalan karena manager/vtable pada path tersebut belum tentu valid saat startup awal diagnostic DLL.
Runtime comparison yang teramati berbentuk:
left = stateA
right = normalized_response
Comparator original mengembalikan 0 ketika equal dan non-zero ketika berbeda. Trace mencatat original return value serta label equal / different; hasil comparator tidak diganti.
High-level validation model
producer_input
|
v
MD5_HEX
|
v
stateB
|
+-----------------------> HTTP request k=stateB
|
v
stateB + "aktif" + stateB
|
v
MD5_HEX
|
v
hash1
|
v
MD5_HEX
|
v
stateA
HTTP response
|
v
normalization
|
v
stateA ----------------------> comparator <--- normalized_response
|
v
original target decision
Kenapa runtime instrumentation dibutuhkan
Static analysis bisa menunjukkan imports, strings, signatures, global addresses, dan candidate control flow, tetapi tidak selalu menjelaskan nilai aktual yang bergerak antar-stage. Runtime tracing mengisi bagian itu dengan data konkret.
Pada kasus ini, instrumentation membuktikan hubungan antara producer input, stateB, concatenation dengan literal aktif, first hash, second hash menjadi stateA, transport stateB melalui HTTP, normalization response, dan final comparison terhadap stateA.
Build diagnostic
Target-specific tracing menggunakan build Win32/x86. Toolchain yang digunakan dalam project adalah CMake dan Visual Studio C++ dengan MinHook.
cmake -S . -B build-x86 -A Win32
cmake --build build-x86 --config Release
Output diagnostic utama meliputi DLL instrumentation, diagnostic launcher, authorized host/launcher, dan module observer untuk pengujian terkontrol.
Kesimpulan teknis
Temuan utama bukan sekadar keberadaan satu validation function, melainkan sebuah data-flow yang konsisten. stateB dihasilkan dari runtime producer input dan dikirim melalui network, sedangkan stateA dibentuk melalui dua tahap MD5 tambahan dan tetap lokal sebagai nilai pembanding terhadap response yang telah dinormalisasi.
MinHook digunakan sebagai telemetry layer untuk menghubungkan static reverse engineering dengan nilai runtime aktual. Dengan mempertahankan original trampoline dan original return value, trace dapat dipakai untuk menjelaskan behavior native program tanpa mencampurkan hasil observasi dengan behavior hasil modifikasi.
Penutup
Analisis V1 menunjukkan pentingnya menggabungkan module discovery, xref scanning, ABI verification, state-generation tracing, network telemetry, dan comparator observation dalam satu model. Setiap stage memberikan konteks yang berbeda, dan korelasi antar-stage menghasilkan gambaran validation pipeline yang jauh lebih akurat daripada hanya melihat satu function atau satu packet secara terpisah.