Jump to content
Tuts 4 You

Antidump methods


Pancake

Recommended Posts

Hi. i was lookin for answer on google and here but i didnt find it. So, could someone explain why are CPUID and RDTSC so important when unpacking? And how does stack/heap antidump work?


 


Thanks in advance


Link to comment

Basically:

RDTSC is a timestamp counter, which can be used to calculate execution time delta values. The idea behind this is that you execute a RDTSC at some point of your code and again after a block of instructions. After it has been executed again, the first timestamp value is compared to the second to determine how much time has elapsed executing the code between the two RDTSC instructions. If the time delta is larger than some set value, you can assume that a debugger has control over the program. This approach works especially good around a code block that creates an exception on purpose, as the debugger needs to "handle" the exception and later on pass control to the application again. I think I read somewhere that this approach is not reliable on multi-processor systems because of sync uncertainty.

CPUID can be used as an antidump by executing it at some point of your application and storing certain returned processor characteristics. Later on your application can call CPUID again and compare the result with the stored characteristics. If they differ, the processor is not the same as the one used to create the values first. In practice this means that the protector stub was not run by the same processor as the dumped code is run on.

Stack and heap antidumps work a bit similar with the CPUID idea. The protector stub generates a value and moves it to a specific place in the stack or allocates the value on a heap. When the dump is run again, the stack and heap will be initialized by the system. This means that the previously stored values do not exist anymore. So once a check executes at some point in your dump, the result will either be a different value or an access violation.

Edited by HellSpider
  • Like 5
Link to comment

That made things much more clear :) I found a beautiful CPUID vm handler (im not goin to run dump on other pcs so its not that imporant tho), but how can i start tracking down heap and stack?


Edited by Pancake
Link to comment

By the way, what with tls callbacks? For example g++ compiler uses tls callbacks to initalize soem stuff, and after such file is protected the packer's stub will call the tls and if i dump it on OEP the dump will have the tls section missing? So what will happen to tls afetr unpacking?


 


So after unpacking DELPHI themida app i noticed that tls section' callback are zeroed out and working. But wait, every delphi app should have the tls section right? So after moving to vmp delphi unpackme dumping with scylla saved me the tls section with 1 callback (which is not executed even once in packed file) and running dump with the tls caused to crash. When i zeroed out the tls it worked perfectly. Im lost, can someone explain whats goin on here?


Edited by Pancake
Link to comment

By the way, what with tls callbacks? For example g++ compiler uses tls callbacks to initalize soem stuff, and after such file is protected the packer's stub will call the tls and if i dump it on OEP the dump will have the tls section missing? So what will happen to tls afetr unpacking?

 

So after unpacking DELPHI themida app i noticed that tls section' callback are zeroed out and working. But wait, every delphi app should have the tls section right? So after moving to vmp delphi unpackme dumping with scylla saved me the tls section with 1 callback (which is not executed even once in packed file) and running dump with the tls caused to crash. When i zeroed out the tls it worked perfectly. Im lost, can someone explain whats goin on here?

 

 

TLS stands for Thread Local Storage, so its ideal to think that when you are doing multi-threading computing, sometimes you need to store static (but local) memory on the thread itself - because in some situations you don't want a global variable to avoid race conditions among several different threads. The point is that in addition to storage, you will also need variable initialization reason for which thread local storage *callbacks* are called. This can include arbitrary code, as it is possible to do so in any c++ constructor function. So, because of this fact, evil minds can override the TLS callback table to produce malicious code, or unpacking code. The advantage of this approach is that it will fool most noobs, because debuggers, by default set a breakpoint on the application entry-point and simply don't take into account the existence of possible tls code, hance when you 'load' your binary in a debugger you already executed code you didn't even see. Having said this, I guess that in both cases you are only looking at the packer generated tls table, which would make sense since you don't want to execute a vmp callback after having a unpacked code - would only make sense that a crash would happen, but its just a wild guess.

Edited by xSRTsect
  • Like 2
Link to comment

I know how tls works but i did not fully understand the interaction of tls with packers. Anyways now i moved on to next target (VMP 2.06 by LCF-AT) with boxed dll and this seems bit harder :) I see it simply calls LoadLibrary and hooks many NT apis responsible for mapping the dll so they get redirected to memory instead of lookin for file.

So call to (hooked by vmp) NtMapViewOfSection does everything at once: allocates memory, maps the file and then i can analyze PE header. I find the EP (the boxed dll is also VMP packed) and import table (imports arent resolved yet) and i put HWBP on EP. Then i resume execution and i land where i wanted. I see that the imports have been resolved and i want to dump it here. So in scylla i select boxed.dll, set the EP, IAT and size, everything is green and then dump. The file is running but im gettin VMP error that the checksums are wrong "file been cracked" or something like that.

 

So possibilities are 2:

1) Unpack the boxed dll when its loaded in packed main.exe <-- hard

2) Find raw data of the dll <--- impossible for me

 

Any suggestions?thanks in advance :)

Edited by Pancake
Link to comment

So, because of this fact, evil minds can override the TLS callback table to produce malicious code, or unpacking code.

 

You can even abuse the TLS table to point to invalid callback addresses, which will cause access violations when running in a debugger but will run normally in Windows. Sure, might be drastic, but it seems to work.

  • Like 2
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...