Archive for the ‘win32’ Category

# IDA-Pro 5.4: old bugs on the new streets (was: to download or to not download)

IDA-Pro 5.4 has been released. aside of many positive changes it’s just a huge bug-fix. take the old bug with zero-based PE-files for example. I reported it to Ilfak long before 5.3. now it’s fixed and following pictures taken by Elias Bachaalany (the clever guy working for hex-rays) proves it.
not good for me, coz I was going to talk about it (and many other IDA-Pro bugs) on Code Gate 2009 security conference in South Korea . well, never mind. I have enough time to redesign my syllabus

dead bug

dead bug

TLS flooding bug (also discovered by nezumi) has not been fixed yet. um, going to write a short article how to fix it with _your_ hands.

 

# Baghdad – dead alive breakpoints

not Baghdad actually, just Borland stuff. it’s russian jargon. borland => baghdad (they sound quite similar). well, you want to hack a Baghdad program? and breakpoints do not help you to hack it fast? well, guys…

set breakpoints on library functions. IDA-Pro recognizes them and once they have been recognized and addresses determined – feel free to use any debugger – Olly or Soft-Ice.

the most interested functions are listed bellow (of course, the list is incomplete, just gives you an idea what to do):

@TControl@GetText$qqrv ; TControl::GetText(void)
@System@@LStrCmp$qqrv ; System::__linkproc__ LStrCmp(void)
@Sysutils@Now$qqrv ; Sysutils::Now(void)
@Sysutils@DecodeTime$qqr16System@TDateTimerust2t2t2 ;; Sysutils::DecodeTime(System::TDateTime,ushort &,ushort &,ushort &,ushort &)
@Sysutils@StrToInt$qqrx17System@AnsiString ; Sysutils::StrToInt(System::AnsiString)
@Controls@TControl@SetVisible$qqro ; Controls::TControl::SetVisible(bool)
@Controls@TControl@SetText$qqrx17System@AnsiString ; Controls::TControl::SetText(System::AnsiString)
@Mask@TCustomMaskEdit@GetText$qqrv ; Mask::TCustomMaskEdit::GetText(void)

btw, there is a good plugin for Olly – GoDup (by godfather+) allowing to use IDA-Pro signatures directly.

 

# FreeLibrary bug becomes a PE packers bug

there is a way to find out if a program was packed or not. XP/S2K3 has a bug that has to be taken into account unless a packer wants to crash a packed program.

FreeLibrary() does not unload statically linked libraries, but frees dynamically linked ones. consider the following code. it should work. at least it works on XP/S2K3 (W2K is a bug free):

// get USER32 module handle
HANDLE h; h = GetModuleHandle(“USER32.DLL”);

// free the library (3 times just to guarantee the reference count is zero)
FreeLibrary(h); FreeLibrary(h); FreeLibrary(h);

// time to unload
Sleep(3000);

// call any function from statically linked USER32
MessageBox(0,”:-)”,”[x]“,0);

ok, now remove USER32 from the import table and load it on the fly.

// load USER32 and get the module handle
HANDLE h; h = LoadLibrary(“USER32.DLL”);

// free the library (3 times just to guarantee the reference count is zero)
FreeLibrary(h); FreeLibrary(h);FreeLibrary(h);

// time to unload
Sleep(3000);

// call any function from dynamically linked USER32
(int (WINAPI *)(int, char*, char*, int)) GetProcAddress(h,”MessageBoxA”)(0, “:-)”, “[x]“, 0);

wow! the program crashes!!! interesting… but… it has nothing to do with packers! um, actually it has. some packers (and especially protectors) leaves only KERNEL32.DLL there and loads the rest on the fly.

guess, we have a file with statically linked libraries. guess, the program frees one or more libraries doing it deliberately or maybe there is a bug. this bug does not appear, coz FreeLibrary not unloads statically linked DLLs. imagine what happens if we pack the file by packer removes all DLL from the import table? the answer: the program will crash!!!

download the POC (original exe and file packed by RLPack) and test your packer/protector collection.

 

# MS VC – challenge for PE packers

blackd0t () started working on his own PE packer and reached the moment where everything is fine, but MSVC++ 2005 floating point files refuse to work and end up with the runtime error: “R6002: floating point not loaded error” . it’s a common problem. many commercial packers meet the same bug.

well, let’s find out what’s this bug all about! first of all I wrote a simple floating-point program and translated it with Microsoft Visual C++ 2008 (Express). the source code is followed (if don’t have MS VC under your hands, just download the archive):

int a; double x = 1.2f;
for (a = 0; a < 10; a++) x += sin(x); cout << x; return 0;

ok. run it and get 3.14159. the program runs fine! now, we’re going to make “.rdata” writable. why? blackd0t mentioned what he already found out: if “.rdata” is writable, we get the error. the question is why?! maybe there is a bug: if .rdata section is writable – floating point library damages critical data, maybe not, who knows?

open exe with HIEW, press ENTER to go to hex-mode, F8 to call PE-header, F6 for ObjTable, move cursor to “.rdata”, F3 to edit, find “Attributes” there, F3 to edit, change the highest bit from 0 to 1 and press F9 twice to save changes. ESC (twice) to exit.

ops! now we see:

$R6002bug-demo.exe
runtime error R6002
- floating point support not loaded

ok. run HIEW and restore the attributes back. everything works fine as before. load exe into OllyDbg, View -> Memory, find “.rdata” and set memory breakpoint on write. run the program. the program runs fine, nobody tries to write something to “.rdata” section. hm… strange…

ok, ask HIEW to make “.rdata” writable again, reload the file into OllyDbg and run it (with memory breakpoint). the program does not work (the same error), but our breakpoint has been not triggered. what’s a helll?!

make “.rdata” non-writable, reload the file into OllyDbg, View -> Memory and change access of “.rdata” section to RW. run the file. no error! the program works fine.

ok. we got it!!! the floating point library checks not access attributes themselves, but verifies PE-header. go to dump windows (in Olly). press CTRL-G and type the address of the header (400000h in this case). find “.rdata” there and move cursor to 40 00 00 40 (the last DWORD before “.data”). set hardware breakpoint on access and press F9 to run the program, the breakpoint is triggered!!!
how do you like this:

.text:0040E780 __IsNonwritableInCurrentImage proc near
.text:0040E780
.text:0040E782 push ebp
.text:0040E783 mov ebp, esp

.text:0040E7C1 call __ValidateImageBase

.text:0040E7D6 push 400000h
.text:0040E7DB call __FindPESection
.text:0040E7E0 add esp, 8
.text:0040E7E3 test eax, eax
.text:0040E7E5 jz short loc_40E822
.text:0040E7E7 mov eax, [eax+24h] ; !!! breakpoint is triggered here !!!
.text:0040E7EA shr eax, 1Fh

_IsNonwritableInCurrentImage() reads PE-header in order to checks – if its argument belongs to non-writable section.

so, packers are obligated to keep original PE sections layout (or restore only PE header in memory) unless they want to crash floating point applications translated with MS VC and maybe other compilers.

thanks blackd0t for the interesting question!

I wonder: how may packers/protectors will be unable to process this file? going to find out. plz, test all packers/protectors you only have under your hands and leave comments. time to send bug reports :-)

first of all it’s bug of MS RTL – bitch should check real page attributes, not just PE-header!

second of all: numerous packers/protectors do not restore PE-header or damage it to prevent dumping or… disables all PE-header pages (PAGE_NO ACCESS)

 

# chilly suspicions of new win32 bug

wandering over Windows kernel nezumi found very screwy code – another loophole to bypass DEP. W2K SP4 gives PEB/TEB r-w-x attributes, so, PEB and TEB are executable! easy to check it with OllyDbg (View -> Memory).

W2K SP4 gives PEB/TEB r-w-x attributes

W2K SP4 gives PEB/TEB r-w-x attributes

XP SP3 and S2K3 SP1 come without this bug, but what’s about other systems? let’s found out! please, download a simple system info collector (it comes with full sources), run it and send the result to info#re-lab.org or leave your comment here. it’s absolute safe for your system. no harm, no fault.
thanks in advance!

results:
W2K SP4: PEB/TEB are executable;
XP SP3: PEB/TEB are _not_ executable;
S2K3 SP1: PEB/TEB are _not_ executable;

 

# dynamic TLS callbacks instead of SEH

static TLS are not static at all! actually, they’re dynamic. statically declared TLS could be changed in run-time without using any API. it’s possible to register/unregistered new TLS callbacks on the fly even after the file has been loaded.

it was a long story – I tried to found where OS keeps TLS info, but was unable to do it. suddenly something hit me – maybe OS does not keep TLS info at all? maybe OS reads PE file directly? quick investigation confirmed this suggestion. as a matter of fact: OS re-reads PE-header and .tls every time it need the data.

on any following even DLL_PROCESS_ATTACH, DLL_THREAD_ATTACH, DLL_THREAD_DETACH, DLL_PROCESS_DETACH Windows NT reads Data Directories -> TLS Directory. if VirtualAddress isn’t zero, OS reads Address of Callbacks Array and executes the first callback in the list. after it, OS reads the next element of Address of Callbacks Array.

what does it mean? it means: a) we can add/remove new TLS callbacks from another TLS callback or the program; b) if TLS Directory does not fit our needs it’s possible to create the new one on the fly;

guess, we have a program with statically declared TLS callbacks or without TLS at all. the program changes TLS array or creates it from the scratch. how interesting and how useful for malware!

shell-codes and malware sometimes make errors leading to exceptions. not good! thus, malware uses SEH to intercept expectations and suppress them. it was easy. “was” because SafeSEH mechanism has been infixed. too bad for hackers! well, what’s about TLS? if TLS data or TLS callback array belongs to writable memory – no problem to change it on the fly. as it was mentioned before, any exception generated by TLS is suppressed by OS. so, we got what we want.

moreover. guess, a hacker attacking an application, does something wrong and the application crashes. OS terminates it, Dr. Wantons saves the log for future analysis. quite common scenario, isn’t? well, dynamic TLS callbacks is absolute differing thing. TLS callback is called after the critical error, but _before_ process will be finished. in other words, malicious code inside TLS callbacks will be called _after_ Dr. Watson have finished loggin!!!

another thing. add new TLS callback (or create TLS Dir from the scratch), raise an exception (kind of XOR EAX, EAX/MOV EAX, [EAX]) and… pass control to TLS. of course, critical message will appear, but… not every reverser will find out where control is passed after pressing “OK” key.

no matter how TLS info is changed, it might be a local process or something else. yes, it’s possible to add new callback to another process, using WriteProcessMemory.

to demonstrate this I wrote a simple test program adding TLS callback on the fly. download it and run. if you speaker makes “buzz” before and after Message Box it means the program works fine. otherwise: either you have no speaker, either something wrong.

source code is very simple. see it bellow:

BOOL WINAPI TLS_callback_01(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
BOOL WINAPI TLS_callback_02(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);

// TLS callback_01 is declared statically
// TLS callback_02 is not declared yet (will be added dynamically)
DWORD ptr[] = { (DWORD) TLS_callback_01, 0, 0 };
DWORD *xl[] = { (DWORD*) 0xEFBEADDE, ptr, ptr, (DWORD*) xl, ptr, 0, 0};

// this callback is declared statically
BOOL WINAPI TLS_callback_01(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
// add new call-back
if (fdwReason == 1) ptr[1] = (DWORD) TLS_callback_02;
return 0×666;
}

// this callback is not declared statically, will be added dynamically
BOOL WINAPI TLS_callback_02(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
// make sound
Beep(96, 6000); return 0×999;
}

// main function, just to be
nezumi() { MessageBox(0, “press ok to hear buzz”, “[x]“, 0); }

 

# GetProcessDEPPolicy for XP/XP SP2

Iouri Kharon (IDA-Pro coauthor, the guy who created an excellent win32 emulator that works out of pure ms-dos and fits on a single 3″ floppy leaving enough space for system files, FAR manager and a few other tools – unbelievable small, isn’t? he also created a famous UniLink linker ) asked me if I know analogue for GetProcessDEPPolicy for W2K/XP.

this function returns DEP status, telling us do we have non-executable stack/heap or not. it’s very useful for protections, shell-codes and malware, but, um… the problem is – GetProcessDEPPolicy has been appeared only since XP SP3. what’s about W2K or XP SP2 or earlier? the second problem is – sometimes we want to execute code on the stack before the address of GetProcessDEPPolicy will be found.

the solution is simple. just try to execute any code (like RETN) on the stack and if you get an access violation exception – it means DEP is enabled and otherwise. it’s very easy. just a few assembly lines, but it might be even simpler!

any exception raised inside TLS callback is suppressed by OS and isn’t delivered to the app. what it means? it means that trying to execute code inside TLS we’re not obligated to catch exceptions! if DEP is on, OS just terminates TLS callback, so posterior code will be not executed.

to demonstrate this I wrote a simple test program. you can download it with a source. it has no assembly in-lines, but was tested only for MS VC. compile it, open exe with HIEW hex-editor. press ENTER to go to hex-mode. F7 (search)m type DE AD BE EF. move cursor to the next byte after “DE AD BE EF”, see current virtual address (right-top corner of the screen). in our case it’s “PE.4002F8″. convert VA to RVA (i.e. 40002F8 ->2F8). press F8 to call PE header, press to F10 to display Directories, find “TLS” there, press F3 to edit and change RVA to our RVA (in our case it’s 2F9) and make size == 20h. F9 to save changes and Escape (press twice) to close the dialog and exit.

now, run the exe and see DEP status.

#pragma comment(lib, “USER32″)
#pragma comment(lib, “KERNEL32″)
#pragma comment(linker, “/ENTRY:nezumi /SUBSYSTEM:WINDOWS”)

char dep[] = “DEP is on!”;

BOOL WINAPI TLS_callback(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
int ret = 0xC3;
if (fdwReason == 1)
{
ret = ((int (*)())&ret)();
*((WORD*) &dep[sizeof(dep)-3]) = ‘ff’;
}
return 0×666;
}

nezumi() { MessageBox(0, dep, “[x]“, 0); }

DWORD ptr[] = { (DWORD) TLS_callback, 0 };
DWORD *xl[] = { (DWORD*) 0xEFBEADDE, ptr, ptr, (DWORD*) xl, ptr, 0, 0};

 

# TLS callbacks w/o USER32 (part III)

the story had a continue. read this:
Peter Ferrie> The requirement is not user32.dll, just a DLL
Peter Ferrie> that imports from kernel32.dll. I changed tls-nousr.exe
Peter Ferrie> to import from kernel31.dll instead of kernel32.dll.
Peter Ferrie> I created a kernel31.dll that imports from kernel32.dll
Peter Ferrie> the LoadLibraryA and GetProcAddress, and also exports them.
Peter Ferrie> The TLS code runs normally in that case.
Peter Ferrie> For the OllyDbg case, maybe a plug-in called LoadLibrary(“kernel32″)
Peter Ferrie>from inside the process. It’s probably some reference counting thing.

yeah, right. I figured out that the MSVCR71.dll is suitable as well (see my previous post), just not changed the subject. anyway, it’s a bug of XP/S2K3 and eventually we found a workaround for it.

I wonder if Vista is buggy or it has been fixed there? guys! if you have Vista under your hands, plz, run the examples and tell us the result. thanks!

 

# TLS callbacks w/o USER32 (part II)

Peter Ferrie posted an interesting comment on my previous article. I decided to reply here, coz not everybody reads comments, but it’s discussion worth to be read.

Peter Ferrie> That’s not correct. You can’t display a message anymore from a TLS callback
Peter Ferrie> because USER32 is not initialised at that point,

I don’t try to display a message from TLS callback, I try do _not_ display it :)
XP SP3 and S2K3 allow me to call MessageBox form TLS, Vista does not, but I’m not talking about calling something from TLS. the point is – if there is no USER32, TLS isn’t called at all. check out FSC08_Level2.exe. it’s F-Secure’ crack-me, written by Kamil (very clever guy!), who packed a file with UPX and added TLS callback, thus “upx -d” loses the TLS. it’s easy and you probably noticed this. but you definitely missed the point. there is MSVCR71.dll!exit there that is imported, but not actually used. UPX does not use MSVCR71.dll, so it was added by someone else. guess it was Kamil :-) who added it manually. but for what’s reason? the answer is – without it XP and S2K3 refuse to call TLS. so, F-Secure guy met the bug and found the workaround. it proves that I’m right and the bug does exist :-)

Peter Ferrie> but it does really run. Create a TLS callback that looks like this:
Peter Ferrie> mov eax, dword ptr fs:[30h]
Peter Ferrie> l1: cmp byte ptr [eax + 2], 0
Peter Ferrie> je l1
Peter Ferrie> int 3
Peter Ferrie> and run it. The file will wait until the debugger attaches.
Peter Ferrie> That shows that the callback is running.

guess, your TLS callback is executed when the process is about the end, you don’t check for the reason argument. could you please show me your exe file? I show you mines. plz, download two examples. they are very simple:

#define Msg (int (WINAPI *)(int, char*, char*, int))
#define Box GetProcAddress(LoadLibrary(“USER32.DLL”),”MessageBoxA”)

#define TLS_B ” not”
#define TLS_C ” executed! *\n\n”
#define TLS_A “\n* TLS callback has been”

char TLS[] = TLS_A TLS_B TLS_C;

BOOL WINAPI TLS_callback(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if (fdwReason == 1) memmove(&TLS[sizeof(TLS_A)], &TLS[sizeof(TLS_A TLS_B)], sizeof(TLS_C));
return 0×666;
}

nezumi(){Msg Box (0, TLS, “[x]“, 0);}

DWORD ptr[] = { (DWORD) TLS_callback, 0 };
DWORD *xl[] = { (DWORD*) 0xEFBEADDE, ptr, ptr, (DWORD*) xl, ptr, 0, 0};

TLS callback just removes “not ” from the string displayed from the main functions. compile it, apply TLS Dir and run. under W2K TLS is executed, but it does not executed under XP/W2K3, however if you replace GetProcAddress(LoadLibrary(“USER32.DLL”),”MessageBoxA”) by a direct MessageBox call it will work fine.

btw, I found another interesting thing. run TLS-nousr.exe under Olly 1.10 (have not checked another ver) under XP/S2K3. ops! TLS callback is called. ok, run it under IDA-Pro debugger (console ver). wow! it’s not called! so, OllyDbg forces system to execute TLS somehow. have not found out how yet.

 

# another EnableTracing() bug

looks like IDA Pro 5.3 has another bug. EnableTracing()/GetDebuggerEvent(WFNE_ANY, -1); returns 10h (BREAKPOINT) on function calls thanks to internal IDA-Pro breakpoints. IDA-Pro sets breakpoints after calls to perform step over tracing (TRACE_FUNC). Soft-Ice and OllyDbg do the same thing. the problem is – EnableTracing() does it every time, even we ask it for TRACE_STEP or TRACE_INSN. IDA-Pro should hide internal breakpoints, but she forgets to do it!

not good for us! well, how we’re going to handle this? um, r_eip = GetEventEa() points to the next instruction after the call and GetBptAttr(r_eip, BPTATTR_EA) = = -1, where -1 means no breakpoint here. why? coz, GetBptAttr() hides internal breakpoints, but GetDebuggerEvent() does not. so, it’s definitely a bug. normally, debuggers always hides internal breakpoints – nobody wants to confuse users. well, IDA-Pro does.

another bug: a real breakpoint just freezes IDA-Pro and GetDebuggerEvent(WFNE_ANY, -1) will never return, so we have to specify the second argument (time to wait), calling the function like this: GetDebuggerEvent(WFNE_ANY, 0×3). of course, if GetDebuggerEvent() returns DBG_TIMEOUT we have to check for real breakpoints. if GetBptAttr(r_eip, BPTATTR_EA) = = r_eip it means that a real breakpoint is here. it’s a simple heuristic algorithm, but it works!

I wrote a simple script to demonstrate how to use EnableTracing(). download it and run. the output should look like this:

IDA says breakpoint:
00402CECh:call ds:HeapFree
00402CECh:pop esi

IDA says breakpoint:
00401AC4h:call _calloc
00401AC4h:pop ecx

IDA says breakpoint:
00401067h:call _printf
00401067h:add esp, 10h

4010B0: hit breakpoint
heuristic says breakpoint!

did you see this? IDA-Pro stops at every calls!!! so, the final version of the correct tracer should look like this:

// start tracing
EnableTracing(TRACE_XA, 1);

// wait for any debug even
code = GetDebuggerEvent(WFNE_ANY | WFNE_CONT, MAX_WAIT);

while(1)
{
r_eip = GetEventEa(); // next even eip

if (code == BREAKPOINT) // <<< IDA BUG!!! Message("IDA says breakpoint:\n%08Xh:%s\n%08Xh:%s\n\n", r_eip, GetDisasm(PrevHead(r_eip, 0)), r_eip, GetDisasm(r_eip) ); if (code == DBG_TIMEOUT) // exit due to timeout { // check for breakpoints if (GetBptAttr(r_eip, BPTATTR_EA) == r_eip) // real bp Message("heuristic says breakpoint!\n"); break; } // check for errors if (code < 1) break; // wait for a next event // MAX_WAIT (time to wait, sec) - prevents IDA freezing code = GetDebuggerEvent(WFNE_ANY, MAX_WAIT); }