Freigeben über


Obfuscate your code

Obfuscation is widely used to protect your code from reverse engineering.
Here is one example which takes advantage of indirected call and opcode overlap in X86:

__declspec(naked)
void Fun1()
{
     __asm {
         //obfuscation chunk
         call LABEL1
LABEL1:
         pop eax
         add eax, 6
         jmp eax
 
         //real function body
         ret
     }
}
 
__declspec(naked)
void Fun2()
{
     __asm {
         //obfuscation chunk
         call LABEL1
LABEL1:
         pop eax
         add eax, 7
/*
         jmp -1
         jmp eax (merged with the previous instruction) 0xEB 0xFF 0xFF 0xE0 -> 0xEB 0xFF 0xE0
*/
         __emit 0xEB
         __emit 0xFF
         __emit 0xE0

         //real function body
         ret
     }
}

int main()
{
#if 0
     Fun1();
#else
     Fun2();
#endif
}

In Fun1, the obfuscation chunk do the following work:

  • Get the current EIP (LABEL1)
  • Adjust the EIP to the target function
  • Jump to the target

In Fun2, it merges the two jump instructions which will confuse the disassembler. To make the analysis even harder, we can rely on the fact that “add eax, 7” (assume the real function body is after our obfuscation chunk) will never overflow, and replace “jmp –1” with “jno -1”. Or we can use more complicated arithmetic to compute the target address.

Other kinds of obfuscations include:

  • API Call Obfuscation (LoadLibrary+Encrypted Parameter)
  • Data Encryption (String Literal)
  • Code CheckSum + AntiDebugger
  • Dynamic Data Extraction

Comments