Link to home
Start Free TrialLog in
Avatar of controlr
controlrFlag for Israel

asked on

Delphi 2010 Hacker proofing

We wrote a Delphi EXE  and we have severe hacking concerns.
1. We put the "sensitive" code in places away from the main form.
2. We dont want to crypt the exe as it will slow performance and will become an issue.

We want to verify DeDe or any otherDecompiler can not decompile D2010.

Is that so?
if so, to what extent can they decompile (mainForm or all) ?
Avatar of 8080_Diver
8080_Diver
Flag of United States of America image

Check out this link:
http://www.softpedia.com/get/Programming/Other-Programming-Files/Shrinker.shtml
I have used Shrinker for some time now.  It compresses the file so that it decompresses into memory (i.e. it is not decompressed to disc before loading).  THat reduces disc read time and network transfer time.  The net effect , if the executable is stored locally, is hardly noticable compared to loading the uncompressed executable and, if the app is pretty big, may actually improve the speed of initiating the app because of the decreased disc read time.
NOTE: I am not affiliated in any way with the author of Shrinker.
Avatar of aikimark
I'm a fan of Themida, by Oreans software.  One problem with disk-image protection is that it doesn't protect your secrets when the program resides in memory.  Dumping memory is one of the techniques used by crackers/hackers.
@aikimark,
So, how does Themida work?  Can you still use DLL's?
@8080

Themida is an obfuscator.  I haven't tried using Themida with a DLL, but the protection process does list DLL as an eligible file type, so it should be possible.  I'm working in the 32-bit environment.

========
@controlr

Is your Delphi2010 application a .Net application or a 32-bit application?
Avatar of controlr

ASKER

its a Win32 application. there are no .net plug-ins at all !
If a hacker dumps the memory at runtime, can they really see whats going on in the code in terms of how it really works ?
Would this be the same if i make my app as a plug-in ActiveX (ocx for browser)?
If so, i meay need to reconsider making it a web plug-in.
 
@8080_Diver,
By using Shrinker.. will it be impossible to decompile ?
and to all.  Are there any other decompilers asdide from DeDe that can get into my exe ?

About the runtime memroy dump.. im assuming they will see the RESULT DATA as oppose to the process. Cant really do anything about that.  but can they actually see the "LOGIC" of the code ?
@controlr,
Shrinker obfuscates the code by compression.  In other words, it's kind of like a ZIp file.  However, it also has an encrypting process.  (I don't know what it uses and probably wouldn't tell if I did. ;-)
As for decompiling . . . well, first you'd have to expand it and to do that you'd have to figure out the encryption and compression/decompression algorythm, so, I don't know of wanyone who ahs gone to all that trouble.
It also lets you Shrink DLL's and then just use them "normally"  (I've dne both static and dynamic DLL loading with them "Shrunk".)
As for the memory dump trick to hacking . . . well, let me put it like this, if your processes as so valuable that someone would go to that trouble, then you would already know have to prevent it.  If they can figure out where everything starts, they can not only see the data but also the logic/processing.  They could theoretically use a disassembler to extract the assembly language equivalent to your application; however, I have worked with disassembled applications and, unless they are fairly small, that code gets ugly in a hurry.  Again, it gets back to "What's it worth to you?" . . . but from you stand point and from the hacker's stand point.  
There are several decompilers/disassemblers that can "get into [your] code" . . . and most hackers either build their own or have their favorite flavor. ;-)
IMHO, though, the bottom line is, what's it worth to you?  If it is valuable enough to get major heartburn over it, then spend the money to get a good tool.  If you're just being paranoid, then use something like Shrinker because it is probably a "good Enough" tool.
@ 8080_Diver,
Thanks, thats great stuff. just to clarify something though. I wil explain.
Is a client/server application. the data is ecrypted on the server's end.  The server sends the data to client, the client also receives a session KEY from another server, thus unable to decrypt incomming server messages unless its the rightful client.
Even if a hacker gets the code figured out.. they whould have to get the session key. tahts gonna be kinda hard. so im not too concered.
 
I am concered with what you have said about decompilers out there. and will have to change the code logic often with version checks to tire-out the hackers.
and my user-base will attract MANY hackers :( so im trying to prepare accordingly.

You said, hackers make their own decompilers. Does it make a difference that we use D2010 in ANY WAY at all ??

And 1 last thuoght about "shrinker". If someone has a good decom and i use shrinker, they cant really decompile it, can they? they can only get the mem-dump? no ?
 
Thanks so much! wish i could give moar points :)
Before using Shrinker, you should be aware of DeShrink by j0b.  It is a reverse engineering tool used by crackers.  It looks like the most recent version is 1.6.
then kinda makes shrinker useless haha..  how about the rest of the above issues  ?
I won't get into this issue because it's an impossible one to solve. I will point out one of the main flaws of most protectors: If you suspend the application remotely you can bypass all defenses that a program like Themida protects your application with. Dumping the file from memory when it's all out in the open will be a breeze.

Now:
"If a hacker dumps the memory at runtime, can they really see whats going on in the code in terms of how it really works ?"
Completely. They will have your entire source code(in asm of course). If your application is really worth their time they will get through it.

The only real way to protect against this is virtualization which Themida does support. Basically you place code markers in your functions/procedures that only decrypt the function when it's being used, it's then run away from the original base then re-encrypted(a very simplified way of explaining it). The only down side is speed cost. If your using it on a function that is called many times in your application it will slow to a crawl.

Now, I'm not trying to discourage you, but you can only disinterest crackers and hackers, not stop them.

You have to ask yourself: Is the time, money, and effort going to outweigh my losses if my application gets cracked?  
Hi ControlR.

Few words about Themida.
I like it too...i use it too. It was made by one of my professors.
I know the bright sides and the dark ones too. I wouldn't suggest it for a big/professional release. There are down sides that you should consider. There are tools to defeat Themida.

Negatives :
1) It patches the windows Kernel. Many anti virus do this too. This is the core of windows.
Microsoft introduced PatchGuard or Kernel Patch Protection to avoid this.
"Patching the kernel" refers to unsupported modification of the central component or kernel of the Windows operating system. Such modification has never been supported by Microsoft because it can greatly reduce system security and reliability. However, though Microsoft does not recommend it, it is technically possible to patch the kernel on x86 editions of Windows. But with the x64 editions of Windows, Microsoft chose to implement technical barriers to kernel patching....Kernel Patching can still prevent system stability and reliability problems caused by legitimate software patching the kernel in unsupported ways....

Patching the kernel has never been supported by Microsoft because it can cause a number of negative effects, which include:

The Blue Screen of Death,Reliability issues resulting from multiple programs attempting to patch the same parts of the kernel.Compromised system security.Rootkits can use kernel access to embed themselves in an operating system, becoming nearly impossible to remove."Products that rely on kernel modifications are likely to break with newer versions of Windows or updates to Windows that change the way the kernel works."


2)A monitor program has been found running in your system. Please, unload it from memory and restart your program”.
Themida stops execution of your program if legitimate software are found in the system. Or if there are not in the system and you've just run it on the current windows session and delete it !
Some of those tools belong to SysInternals a software company that belongs to Microsoft !!
The big head ache is that there is no information about the software that
caused Themida to exit !!!
So you might expect a lot of your customers to call you and say there is a problem, application crashes with no info and you'll be in the difficult position to ask them to remove a big list of legitimate programs... Then reboot to test the program.
For many users PE Explorer has been the equivalent of Task Manager....
"The problem with Regmon, FileMon and Process Monitor is that the driver is loaded all the time in memory even if you close the User Interface for Regmon, Filemon, etc. So, the File system and Registry are still hooked by the monitor driver until you restart the computer."

3) Virtual Machine in Themida can make your application very very slow.
4) Increase in file size (400Kb - 2Mbyte)
5) There are tools that assist other tools to successfully dump the memory of a protected application.
6) When an application is targeted it will get cracked.
7) Themida some times (many) creates false positives. Anti virus detect it as a threat.

Beside this... i think its a great tool.
1) It requires special study for each executable. There are no universal unpackers
2) There are no loaders

In my opinion you can use :
1) Anti-debugger code within your code
2) Encrypt or work with the hash of sensitive data (strings).
2) VMProtect (very good) or Themida or StrongBit ExeCryptor
3) Armadillo (SoftwarePassport), AsProtect to pack the application.

Hope this helps...
As I originally stated, there is no way to stop hackers from hacking your software.  Actually, I should amend that to "There is no functional way to . . . ".
If you truly do not want your software stolen/hacked/reverse engineered, then you have 2 options:
  1. Destroy all copies of the source code and executables and destroy all data storage that has ever had the source or executables on them.
  2. Unplug your computer from everything and seal it in a concrete box with no openings and drop it in someplace like the Marianas Trench.
Since both of those options, effectively, invalidate any conceivable opportuinity to use the software,  they are nonfunctional.  However they will protect the source code and executables.
So, back to my question, "What's it worth to you?"
If your software is going to attract many, many hackers, then, even if you buy the latest and greatest encryption/compression/protection tools, you are going to be hacked.  The best you can hope for is to make it very hard to do that . . . however, that can act as a challenge to hackers and attract even more. ;-)
Shrinker can probably be hacked . . . and your point is . . . ?  It makes it rather difficult and it doesn't screw around with the Kernel and it doesn't whine about legitimate software running.  (It does, however, void any chance of compiling in debug mode, Shrinking the executables, and then debugging them . . . but would that be kind of a dumb thing to try anyway? ;-)
As I also stated early on, I am not in any way affiliated with the author of Srhinker . . . I have just found good justification for its use. ;-)
I might write an article on these rules-of-thumb.

* With Themida, you only mark the sensitive sections for obfuscation/virtualization.  Most of your code runs normally -- with the usual Delphi optimized performance.

* Trust no one

* Trust no part of Windows -- Windows APIs can be spoofed and wrapped.  Any call to the Windows Crypto library can be used to steal your encryption key.

* Trust no part of the network -- your messages can be intercepted and replayed and altered.

* Don't put your (protection) eggs in one basket -- sprinkle license check routines around your application.

* Add some randomization to the license checking -- you might use a timer or (pseudo-)random number to create some air of mystery for the cracker/hacker.  Consistency of action is their friend.

* Make frequent changes to your code, with concomitant changes to your protection keys.

* If you keep some data on the local hard drive, distribute it or add redundant checks.

* Add a feature to create a dump of the application data store and application registry entries for remote debugging.

* Add a feature to correct any licensing errors -- the 'fix' files need to be time sensitive, preventing replays.

* Use time-sensitive license files that include enough data that it uniquely identifies the user and the environment.

* (already stated above) Come to an agreement with your management on the value of the application and data.  Decide how much time and money is prudent to protect that asset.

* Understand that there is no fool-proof protection of your digital assets once it leaves your server.
Thanks for all the inputs, before giving away the points, just 3 roundup questions..

1. If a GOOD cracker was to see the mem-dump, how long would it take them to get their heads around how the program works?

2. If Irelease updates on weekly basis, is that enough of a deterant so crackers dont get too attached to it?  or will it only attract more crackers?

3. At what point would a cracker "give-up" for example, after seeing 10-30 crack-proof routines?  50, 100 ?  idk.. just a thought.  

And to answer the question from prev notes.. this software is bigger than the new APple announcement, so, yeah... protecting it is important for us.

Thanks to all for inputs.  points will be deistributed after this reply.

controlr,
Shazbat!
My answers to your questions:
  1. How complex is the software? Are there any obvious clues (e.g. text constants) to aspects of the application? If you were to review a disassembled version, how long would it take you (even knowing the app) to get your head wrapped around it? Is it worth enough to you to hire a "white-Hat" cracker (i.e. one who, in effect, tests your security rather than actually trying to break in to steal your secrets)?
     
  2. I would say that, as long as you change things around enough (notice that fuzzy term "enough" ;-), that would definitely help. However if you have a 5 Gb app and only alter 128 bytes of it for any one release, then, no, it won't matter a bit.
     
  3. If it is that valuable, then at least one hacker out there isn't going to give up. Some just take 50, 100, 1000 failures as an afront to their abilities and a challenge and they become even more determined. ;-)  
If the app is that valuable, then I would recommend researching to find the latest, greatest and strongest encyprtion/obfuscation tool out there. Then keep researching because it is like a game of ping-pong. First you defeat the hackers, then they defeat your security, then you get better security, then the hackers defeat that, . . . .
If your application is 'bigger than the new Apple announcement' then you should spend a LOT of money and time protecting your investment.  You would need to do a lot of explaining to convince us that it is *that* valuable.

A little context would be helpful:
1. What is the nature of the application? (accounting, game, database utility, etc.)
2. How many beta (or current) users do you currently have?
3. How many licensed users do you expect in the next .5, 1, 1.5, 2, 3, and 5 years?
4. What is the target retail price for your application?
5. What is your licensing scheme? (seat, CPU, network, leased, purchased, etc.)
6. What is your license validation scheme?
1. social interaction
2. Beta (5k)  with waiting list for release of 30k
3. Free: 500K, 20M, 250M+    Paid: 5K, 200K, 2.5M+
4. Monthly membership @ $10/personal, $50/Business
5. Per user
6. private-scheme of advanced remote-server-verification. NOT getting into the details...
A social interaction application architecture should require user authentication.  As such, you can enforce licenses at the server (message exchange).  I recommend you give away the software.
I have to agree with aikimark.  If you approach this from the other direction, i.e. enforce licensing issues and usage from the server, instead of trying to protect your front end, you ca basically give away the software (Which may up your usage some ;-) and still contorl the monetary aspects.
Hi,
  why don't you use Alladin HASP keys ? They have a special procedure which protects your software from reverse enginering. The SDK is free, you only pay for the HASP usb Keys. This is snippet from their site:

"HASP SRM maintains your competitive advantage by providing the Intellectual Property Protection for your embedded software applications and application data files.

The HASP SRM Envelope is an automatic file wrapper that provides robust intellectual property protection against software reverse engineering through file encryption, code obfuscation and system-level anti-debugging. This ensures that algorithms, trade secrets, and professional know-how embedded in the software are secured against hackers. "

I use them for setting the licence keys in my software...
You just confirmed out bisiness/monetization model; :)  but we still need to control security which is NOT related to COST.. its more related to new technologies that are introduced and we would like to be able to manage the dangers.
Thanks to all for great inputs everyone.  You will hear about this between Feb15 and Mar/15.
 
Again, thanks for all the great inputs.i have to think on how to divide points.  any suggestions ??  
feel free to add more comments, looks like a great relevant thread now.
@twinsoft... Read the thread about numbers and costs..  we are looking at Millions of units, its not a viable solution, esp. @ $10/month per user

Hmm,
  just read the "social interaction" part, that means that HASPs are not an option...

Maybe this will help you, i haven't tested it, but it comes from a reliable source...

You can use conditional ASM statements that actually insert dummy code between valid statements, which can make reverse-dissassembling and single-stepping a nightmare. Actually the garble data never gets executed. These are examples of garble data:

asm
   DB $EB,$06,$55,$44,$55,$03,$a8,$09;
end;

or

asm
   DB $EB,$04,$75,$13,$a2,$14;
end;

You can insert them in your code directly like this

procedure TForm1.Button1Click(Sender: TObject);
begin
 asm
   DB $EB,$04,$75,$13,$a2,$14;
 end;

 ShowMessage('1');
end;

BTW what do you mean by "You just confirmed out bisiness/monetization model" ?

Hi again, i've found the full article here:

http://www.delphi3000.com/article.asp?ID=2986

I had only a part of it...
@8080 and aikimark.. any takes on the viability of the above code ?
@tywinsoft..
"You just confirmed " was to  8080 and aikimark as our business model really give the software free for MOST users but we still need to protect it .

I will try your code. if this is working (without a major performance slowdown).. you just saved me a PILE of work.

Yould still like to see what  8080 and aikimark have to say about this code.  buts its looking like the most "encouraging" thing so far!!!
dividing the points will be a nightmare  :) i   wish i could give more than 500 arrrg.
@twinsoft, did you get a chance to use that code? its looking really good..
 
I still would like to get 8080 and aikimark opinions about this
Hi again,
  I have tested it to see if it causes any problems with apps written in D7. It did not. I did not notice any performance penalty either. I don't know, how or if, the code messes up the decompilers as i don't have one (DeDe or something else). Try to use the full approach with the .inc file as described in the link i sent you (uses random garble data)...
controlr,
Yes, you can do that and it will provide a confusion factor . . . of sorts.  However, if I can find the entry point in the code and start tracing through it, I can quickly determine which routines are called and which are not.  If I find any patters of "code" being repeated and I find one of htem not being called, then I am probably going to look for something calling the rest of them and then, in effect, NULL those sections out.  
If I know that you have used DELPHI to create the product, I will also know that Delphi's compiler will not compile in "dead code" that is never called.  Once I find some "dead code", I know what you are doing.  
I have also seen routines that had an entry point function that would do an XOR on entry and on exit on the memory space occupied by the master routine.  On entry, the entry point routine would XOR the memory one way so that the values in memory became code and on exit it did it another way so that the memory turned back into just binary values.  There was a non-trivial performance cost, though.  
 
irs working great here, and im feeding it data from server !!
This is AWSOME ! you did it!
im closing the thread.  
Thanks to all !!


8080.. do you have any suggestions to makeit HARDER, aside from the code given ?

Like you said, no matter what, it can eventually be cracked.

How long would it take you to crtack that? (knowing its D2009?)
this is part of what happens with Themida.  You mark the start and end points of sensitive code and Themida looks for these in the compiled executable.  It then inserts garbage, misdirection around instructions that it obfuscates and virtualizes.

Your code stays fairly clean.
if this does what themedia does.. im not going to run and get themedia.. ill stick with this. its working nicely actually.
Im just waiting to hear 8080 for a roundup about time for cracking, so we can schedule updates accordingly :)  
I will try to award 500 points each if it lets me
Hi,
  just found something interesting. If you download the demo of the virtualizer product from oceans and go into the Include\Delphi directory you will find some more asm garble examples. Maybe you can use them too...
@controlr

>>if this does what themedia does
Please reread my last comment more closely.  Both of the Oreans protection products alter your executable, but do it in less obvious ways than the ASM blocks you're playing with.

If you are not well versed with the issues, highly skilled with the run time environment and your development tool, you are more likely to create security theater than actual security.

You have the opportunity to resolve issues in this thread before you close it.  It is perfectly acceptable to discuss issues in general terms or alter the specific details (as long as you can map our recommendations to the altered details back to your particular environment).
>>I will try to award 500 points each if it lets me
Do not try to bypass the points structure. It would be a violation of your membership agreement and the EE Terms Of Service.
This is not what Themida does ! Not even the 0.01% of it.
I guess it would take almost a nanosecond to guess whats wrong.
The only application that can not work good with junk code is the unpatched old version of WinDasm.

In general, there are 2 kinds of primitives: checks and land mines.
  • Checks produce a changing value or code execution path based on the status of the item checked.
  • Land mines crash, hang, scramble, or otherwise interfere with the attacker’s tools themselves.
Anti-debugger techniques come in both flavors.

In my first post the #1 thing i said was "1) Anti-debugger code within your code"
An example would be :

1) Junk code :

  • The one Twinsoft posted.
  • This one :
asm
   push 80020441H
   push 80020441H
   push 80020441H
   push 80020441H
   call SetDlgItemInt // call an API which is invalid and will throw an error
   call GetLastError // call GetLastError
   sub eax, 0578h
   add eax, 08h
   mov ebx, offset @End // Move the address of @End into ebx
   add ebx, eax // Will run null bytes and crash
   jmp ebx
@End:
    // This will never be executed in normal conditions. It will pass
   //  null bytes to disassembler and crash it.
   db 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
end;


2) Another one would be to check if Debugger is present.

There is an API for this IsDebuggerPresent(). Check the links.
[MSDN & an example in Delphi]

This is a very simple check. It is extremely general but can be easily bypassed with a breakpoint script or by traditional approaches like patching the import table (IAT). This function merely returns a value from the process memory, it can even be overwritten to always be 0 (False) [by finding Thread Information Block via the %fs segment register, dereference a pointer to the Process Environment Block, and overwrite a byte at offset 2].

Since it is so general, it has little security value but it is a check that would increase the time of a hacker to dump your program.
But simple checks with simple bypass rules can be valuable when you modify them.
Lets say that you call IsDebuggerPresent using SysEnter and then change the Process Environment Block.
You can call Is Debugger present like this:


function SystemCall(ProcessHandle:DWORD; ProcessInformationClass: Pointer; ProcessInformation: Pointer; ProcessInformationLength: DWORD; ReturnLength: Pointer): DWORD;
begin
asm
pop ebp
mov eax, $9A
call @SystemCall
ret $14
@SystemCall:
mov edx, esp
sysenter
end;
end;

function Anti_Process():Boolean;
var
     Ret: DWORD;
begin
Result := FALSE;
asm
mov [Ret], 0FFFFFFFFh
push eax
mov ebx, esp
push 0
push 4
push ebx
push 7
push Ret
call SystemCall

pop eax
test eax, eax
jne @Debugger
mov Ret, 0
jmp @Exit
@Debugger:
mov Ret, 1
@Exit:
end;

if Ret <> 0 then Result := TRUE;
end;

~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
Example of usage :begin    if Anti_Process = TRUE then ShowMessage('Debugger')    else    ShowMessage(' No Debugger')end.


3) Check parent process and exit if not Explorer.
Code pasted below...

4) Enumerate windows and see if there is a debugger window.
Example 1 , Example 2 ...

5) Good code...Use hashes

Very often programmers make real blunders while implementing the registration key validity check when they compare the entered key to its correct value. In this case the cracker can easily find out the correct key value during single-stepping by viewing the arguments used to call the string comparison function:
var ValidRegNumber: String;
...
function CheckRegistration(const RegNumber: String): Boolean;
begin
  if RegNumber=ValidRegNumber then
   Result:=True
  else
   Result:=False;
end;

To avoid this kind of situation during the comparison of the entered key value to its correct value, it is recommended to use their hashes instead of the real values. As a matter of fact, a hash function is a one-way function, which means it is impossible to determine the value of the valid key by checking hashes. Cracking the application will take much more time spent on analyzing the program because it will be necessary to examine far more parts of the code instead of only the procedure of checking whether the entered key is valid:
var
  HashOfValidRegNumber: Longint;
...
// An example of using Peter Weinberger's (PJW) generic hashing algorithm
function HashPJW(const Value: String): Longint;
var I:Integer;
    G:Longint;
begin
  Result:=0;
  for I:=1 to Length(Value) do
   begin
    Result:=(Result shl 4)+Ord(Value[I]);
    G:=Result and $F0000000;
    if G<&gt0 then
     Result:=(Result xor (G shr 24)) xor G;
   end;
end;

6,7,8...) .... Several ...
  • Create a port (NtCreatePort) and set the process DebugPort to this handle. The debug API can’t attach to the process after this since it thinks a debugger is already attached.
  • Alter the process SID to deny access to the process space.
  • Alter PEB. Olly Debugger would bypass most check like this for breakfast but has issues parsing PEB.
  • Trigger exception like StackOverFlow, InvalidHandle. Debugger would not recover nicely.
There are many things left but it would take an article to cover all of them...
Here some interesting articles..."Building a mesh", "Taking the red pill",
"Software protection advice".


Remember
Anti-debugger techniques have a small place in protection schemes, but they can’t stand alone. This is the first step. Nothing more...

Hope this will help a little.

function GetProcessParent(): string;
var
  snap: DWORD;
  pe32: PROCESSENTRY32;
  currprocid: DWORD;
  parentproc: DWORD;
  parentprocid: DWORD;
  parentpath: string;
  isparent: Boolean;
  time_currentproc: FILETIME;
  time_create: FILETIME;
  time_exit: FILETIME;
  time_kernel: FILETIME;
  time_user: FILETIME;
begin
  isparent := False;
  //create snapshot of all processes
  snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if snap <> INVALID_HANDLE_VALUE then
  begin
    pe32.dwSize := SizeOf(pe32);
    //walk through processes to find the current process info
    if Process32First(snap, pe32) then
    begin
      currprocid := GetCurrentProcessId(); //store current process id for faster access
      repeat
        if pe32.th32ProcessID = currprocid then
        begin
          //we've found the current process info
          {
           now we should compare current process start time with the parent process
           start time, to check if the parent process CAN be the real parent
           (process identifiers are reusable, so when the parent process terminates,
           any other process started later on can get the same ID)
          }
          GetProcessTimes(GetCurrentProcess(), time_create, time_exit, time_kernel, time_user);
          time_currentproc := time_create;

          parentprocid := pe32.th32ParentProcessID;
          parentproc := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, parentprocid);
          if parentproc <> 0 then
          begin
            if GetProcessTimes(parentproc, time_create, time_exit, time_kernel, time_user) then
            begin
              isparent := CompareFileTime(time_create, time_currentproc) < 0;
              {
               now we determined, that parentprocess CAN BE
               the parent of the current process
              }
              SetLength(parentpath, 1024); //1024 should be enough for the full path :)
              GetModuleFileNameEx(parentproc, 0, PChar(parentpath), 1024);
              parentpath := PChar(parentpath);
            end;
            CloseHandle(parentproc);
          end;
          break; //do not enumerate any further
        end;
      until not Process32Next(snap, pe32);
    end;
    CloseHandle(snap);
  end;
 
  if IsParent then
   result := ParentPath
  else
   result := '';
end;

Open in new window

@CodedK

EXCELLENT comment.  Maybe you would be a better author for that article I mentioned earlier.  
Thank you Mark.
I'll gather more info and make it more solid and I'll give it a shot.
@CodedK

I'll be glad to help you.
@CodedK,
So, if I understand the "check for a debugger" techniques, that would mean that you could not have something up that you are debugging and then run the application that is being protected by these techniques.  
As ever, there are downside risks to virtually all protection schemes and it becomes a decision regarding what you are willing to accept in the way of hacker/cracker risks vs downside risks vs performance issues.
I would still have to wonder if some of the guys I know who test the security of everything from apps to networks and databases wouldn't catch on quickly to most of the indicated techniques.  It all depends on the level of sohpistication of the hacker/cracker . . . and, for that matter, their _friends_ becuase that "community" will pass on a "challenge" that is too difficult form themselves to a friend who is better and who can, maybe, teach them (or learn) a new trick.
When you consider that various government agencies and the military occassionaly have some one hack their systems, you have to just know that there are some people out there who have nothing better to do than to take on challenges of this nature.  (Of course, in some cases, they may be on another government's payroll. ;-)
on that great link..  How would a the actual VM detect delphi procedure look?
"
26. Detect if running under VMWare or any other Virtual Environment by querying the location of the IDT (since SIDT?can be executed at ring 3 and does not generate any exception this is a reliable detection method). Unlike SoftICE?which reloads the original IDT VMWare simply relocates the IDT to its own internal location. This method is better known as the "Red Pill?Method" and is best described here.
SIDT FWORD PTR opIDT <-- Store IDT.
CMP DWORD PTR [opIDT+2], 0F0000000h <-- Check IDT location (possibly Virtual PC check).
JLE _check_virtualpc
CMP DWORD PTR [opIDT+2], 0FF000000h <-- Check IDT VMWare.
JG_vmware_detected

check_virtualpc:
CMP DWORD PTR [opIDT+2], 0D0000000h <-- Check IDT Virtual PC.
JGE _virtualpc_detected

"

Forgot to respond to the following:
How long would it take you to crtack that? (knowing its D2009?)
For openers, my forte isn't hackin' and crackin' . . . although I do know and have worked with people who were very good at that sort of thing . . . so, how long it would take me is not the real question.  The real question is, how long would it take a reasonably good expert in that area.  Unfortunately, I don't have a very good idea as to how ong it might take.  I do know that one of the guys I used to work with usually took less than a week of effort to crack most applications that he was handed (some of which were, well, let's just say, of a very proprietary nature ;-).  Of course, he also did data recovery from magnetic media (usually to at least 3 layers of history ;-).
The thing is, if it is liable to make somebody a lot of money should they crack you app's security, then they are liable to try until they do it.  That's the whole point, I think, of a lot of this discussion.  You can slow 'em down but you can't really stop 'em.  
@TwinSoft,
Actually the garble data never gets executed.
Are you saying that the following code, in your example, is never called by anything and, yet, it remains in the compiled code?
procedure TForm1.Button1Click(Sender: TObject);
begin
 asm
   DB $EB,$04,$75,$13,$a2,$14;
 end;

 ShowMessage('1');
end;

 
I'll have to look into that one, myself.  The last time I dealt with a Delphi compiler, code that was never called was removed from the final output. :-/
@ 8080
We have weekly updates, sometimes even twice a week. so that is a good thing, since user must download newest version. old version is not supported. Since this is client/server, the logic is on the server where it issues session auth..
Im starting to think i should be protecting the server from remote debug more than the client side.

@CodedK..
How strong/fullprof is that " Debugger is present. "  it sounds really good!
Since we are on the debuggers... What are the most common debuggers aside from softICE that can look into delphi exe's?
@ControlR
You keep asking how strong, how much time.
Everyone has the same answer here and its already been posted.

An example :
  • Lets say that your application has 1000 lines of code. And you will make good money out of it.
  • If you force some person to write 2000 lines of code to defeat it, then he would know so much about your application that he will build it him self and try to get some money out of it...
  • Lets rate this activity with a 100% difficulty then ...
  • The IsDebuggerPresent has 5/100 difficulty to get broken.
  • If you actually implement my suggestions (without packing the application), you get 20/100 difficulty.
  • If you pack/crypt the application you get a 65/100 difficulty.
  • If you use a good packer with obfuscation and virtually execution of small portion of the code then you'll get a 100%.
Another problem is that its a collective work and that needs about 20 persons to make the difficulty drop down to 30% (Its not proportional).
The big problem are the tools. Really only the tools.
If you target the tools then you get rid of the 19 persons out of the 20 pack.

Your application is being downloaded
  • Using a PE Sniffer someone sees what is the Packer / Crypter you used.
  • Searching for an automated tool for the Packer / Crypter.
  • If a generic approach is impossible then > Manual unpacking.
  • Manual unpacking requires several tools :
    Debuggers, memory dumpers, hex editors, disassemblers.

Countermeasures
  • Target the tools ! (kill processes, terminate your application)
  • Use a packer like Themida / VMProtect
    [offer extra layer that would make even the 1st step hard => false results to sniffers].
  • Insert junk code (nop's, extra jumps) use hashing, enforce memory protection.
>> On that great link.  How would a the actual VM detect delphi procedure look?

function Virtual_Pc: boolean; assembler;asm
  push ebp
  mov  ecx, offset @@exception_handler
  mov  ebp, esp
  push ebx
  push ecx
  push dword ptr fs:[0]
  mov  dword ptr fs:[0], esp
  mov  ebx, 0 // Our flag
  mov  eax, 1 // Virtual PC number

  // Call Virtual
  db 00Fh, 03Fh, 007h, 00Bh

  mov eax, dword ptr ss:[esp]
  mov dword ptr fs:[0], eax
  add esp, 8

  test ebx, ebx
  setz al
  lea esp, dword ptr ss:[ebp-4]
  mov ebx, dword ptr ss:[esp]
  mov ebp, dword ptr ss:[esp+4]
  add esp, 8
  jmp @@ret
  @@exception_handler:
  mov ecx, [esp+0Ch]
  mov dword ptr [ecx+0A4h], -1 // If ebx is negativec then its not running  [0 Its running]
  add dword ptr [ecx+0B8h], 4 // Go to the detection code
  xor eax, eax // Handle our exception
  ret
  @@ret:
end;

See additional code pasted below.
------------------------------------------------------------------------------------------------------------
Judging by the numbers you posted, you are addressing a big geographic area.
There is no need to describe what is going on in Russia, China, Korea, Greece, Turkey, Eastern Europe in general. Behind the best packers you see Russian names because security is half the application. So i think you really need to use this approach.



About "Garble data".
Garble data or any other obfuscation technique commonly used in polymorphic and metamorphic software (randomly inserting a sequence of instructions that have no other effect on the functionality of the program) can be removed if those instructions reside inside a decrypted or unsecured application!

Paper : Canonization - Normalization of code
Removing unnecessary code would take about 6 lines of code in an unpacked application. Asside from that there are allready application that do this for you!
This answers again your question : How long does it takes?

To decide if a portion of code is not operational or not :
Article : Satisfiability Modulo Theory


@8080
>>So,if I understand the "check for a debugger" techniques, that would meanthat you could not have something up that you are debugging and thenrun the application that is being protected by these techniques.  

You comment the one line when you are building the application
and testing it inside Delphi!!!

>>Actually the garble data never gets executed.
It does not get executed and it is still there...

{If its true then you are been running inside a virtual environment}
function Virtual_Environment: Boolean;
asm
    XOR     EAX, EAX
    PUSH    OFFSET @@Handler
    PUSH    DWORD PTR FS:[EAX]
    MOV     DWORD PTR FS:[EAX], ESP
    MOV     EAX, 564D5868h
    MOV     EBX, 3c6cf712h
    MOV     ECX, 0Ah
    MOV     DX, 5658h
    IN      EAX, DX
    MOV     EAX, True
    JMP     @@NotHandle
@@Handler:
    MOV     EAX, [ESP+$C]
    MOV     TContext(EAX).EIP, OFFSET @@Handled
    XOR     EAX, EAX
    RET
@@Handled:
    XOR     EAX, EAX
@@NotHandle:
    XOR     EBX, EBX
    POP     DWORD PTR FS:[EBX]
    ADD     ESP, 4
end;

Open in new window

Awsome post  CodedK!

1. What is the real diff between the functions "Virtual_Pc" and "Virtual_Environment:" ?

2. Do you know by chance if the function  "Virtual_Environment:"  was tested on VirtualIron, VirtualBox, VMWare, HyperV ( and Old MS-VirtualPC)  ?  


3. Sorry for the clueless question.. Is a debugger also considered a virtual environment (from the standpoint of either of the functions)?

4. What about sending a CHECKSUM of the "cracked" EXE to the server for login-authentication?  So even if cracked, it needs to send a checksum where its denied access.  That may give a great woraround in the case someone ever does crack it..  Your thoughts ?

5. We need to think about point distribution soon imho, any thoughts?
scratch Q3.. saw it  in earlier answer.. sorry
1) Both of them are working examples.
The first detects Connectix Virtual PC 4.3.2 :
http://download.cnet.com/Connectix-Virtual-PC/3000-2651_4-38862.html
the second detects VMWare.

2) Above is my answer.

3) No

4) You have to protect the function and the check.
Example :

If (file_checksum = "MD5SEVERALCHARACTERS") then
   start_the_application else
Application.Terminate;

Can turn to this :

If (file_checksum = "MD5SEVERALCHARACTERS") then
   start_the_application else (do nothing); <- after disassembly

Or :

If (file_checksum = "MD5SEVERALCHARACTERS") then
   start_the_application else ShowMessage('Another cracked file by someone');

5) If the analysis is good.
wish there was code for detecting if running inside virtualIron / / Virtual box / HyperV.. then this would be an easy closure..

Lets wrap this up.. suggest point distribution scheme
It was a great thread, thanx to all!

im thinking 400 codedK for great  delphi code! and split the rest, perhaps 100 to 8080 ?
VirtualBox
function InVirtualBox:boolean;
var handle:THandle;
procinfo:ProcessEntry32;
begin
result:=false;
handle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
procinfo := sizeof(PROCESSENTRY32);

while(Process32Next(handle, procinfo)) do
begin
if POS("VBoxService.exe",procinfo.szExeFile)>0) then
begin
CloseHandle(handle);
result:=true;
exit;
end;
end;

CloseHandle(handle);

end;

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of CodedK
CodedK
Flag of Greece image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
AWSOME!!  stay on touch xD