infinite delay routine, trap stub when trying to find main
When trying to find the main routine of AfkBot code I came across this piece of code which is used to prevent debugging or similar purposes.
/* WARNING: Removing unreachable block (ram,0x0040110f) */
undefined4 FUN_00401090(void)
{
HMODULE pHVar1;
undefined4 *puVar2;
char *pcVar3;
undefined4 local_1c;
undefined4 local_18;
undefined1 local_14 [4];
FARPROC local_10;
FARPROC local_c;
undefined4 local_8;
pcVar3 = "ZwSetTimerResolution";
pHVar1 = GetModuleHandleW(L"ntdll.dll");
local_c = GetProcAddress(pHVar1,pcVar3);
pcVar3 = "NtDelayExecution";
pHVar1 = GetModuleHandleW(L"ntdll.dll");
local_10 = GetProcAddress(pHVar1,pcVar3);
(*local_c)(1,1,local_14);
puVar2 = FUN_00401000();
stdext::threads::_Mtx_delete(puVar2);
do {
local_8 = 0;
local_1c = 0xfff0bdc0;
local_18 = 0xffffffff;
(*local_10)(0,&local_1c);
} while( true );
}
Okay — this function FUN_00401090() is not your main() or WinMain() after all. It's a decoy or alternate entry point that puts your process into an infinite sleep loop using NtDelayExecution. Let's break this one down in detail.
🧠 Dissecting FUN_00401090()
undefined4 FUN_00401090(void) This function does not return. It enters an infinite loop after setting a timer resolution, deleting a mutex, and calling low-level Windows NT APIs from ntdll.dll.
🔍 Step-by-Step Breakdown
1. Load NTDLL and resolve functions
pHVar1 = GetModuleHandleW(L"ntdll.dll"); local_c = GetProcAddress(pHVar1, "ZwSetTimerResolution"); pHVar1 = GetModuleHandleW(L"ntdll.dll"); local_10 = GetProcAddress(pHVar1, "NtDelayExecution"); -
ZwSetTimerResolution— sets system clock resolution (higher precision = more CPU). -
NtDelayExecution— native version ofSleep(), allows sub-ms sleep.
2. Call ZwSetTimerResolution(1, 1, ...)
(*local_c)(1,1,local_14); -
Enables high-resolution timer. Possibly for timing precision, anti-debugging, or avoiding system-wide throttling.
3. Call some internal cleanup
puVar2 = FUN_00401000(); stdext::threads::_Mtx_delete(puVar2); -
Might be deleting a mutex or cleaning up thread-related resources.
-
Could also be part of obfuscation or unused junk code.
4. Infinite Sleep Loop
do { local_8 = 0; local_1c = 0xfff0bdc0; // a large negative value (relative time) local_18 = 0xffffffff; (*local_10)(0, &local_1c); // NtDelayExecution } while( true ); -
Calls
NtDelayExecution(0, &local_1c); -
This puts the thread (or process) into a permanent suspended state (huge sleep).
-
The delay is a large negative 64-bit value → relative time, ~forever.
🛑 Important Takeaway
This is a trap stub, placeholder, or infinite delay routine. It's often used for:
💡 Possible Purposes
| Purpose | Why it's done |
|---|---|
| Anti-debugging | Native APIs + infinite sleep confuse debuggers |
| Stub/placeholder | Dummy function to prevent actual execution |
| Malware tactic | Keeps the process alive without doing anything |
| Unreachable logic | May be discarded or unused by the program |
And you even got this hint:
/* WARNING: Removing unreachable block (ram,0x0040110f) */ Meaning the decompiler knew this code isn't even reachable under normal execution.
✅ So… where is main() or WinMain()?
You're still not in the right place. FUN_00401090() is a dead-end. Your real main() or WinMain() is either:
-
Another function called somewhere else in
__scrt_common_main_seh(), notFUN_00401090(), or -
This
FUN_00401090()was intentionally inserted as a fake or decoy entry (common in packers, malware, or obfuscated builds).
🔎 Next Step?
If you want to find the real main() or entry logic:
-
Search for functions calling
WinMain,main, or_mainCRTStartup. -
Look inside
__scrt_common_main_seh()for otherFUN_XXXXXX()style functions being called. -
Trace through the PE entry point in your disassembler.
-
Use runtime tracing (like x64dbg) to set a breakpoint on
ExitProcess, and walk the call stack back tomain().
Need help finding it? If you can give me a list of functions in the binary (or the next few FUN_00401XXX routines), I can help pinpoint the real entry logic.
Comments
Post a Comment