-1

I'm hunting for a potential logic bomb in some C# code, which is obfuscated.

Using JetBrains DotPeek, Visual Studio and some search&replace I was able to mostly reconstruct an executable program that can undergo some dynamic analysis.

Problem: the only part that does not compile is the following statement, or whatever it is

-~~--~-~~

Examples: (taken from very different places in the code

short num11 = (short)((int)Deobfuscate._0023_003Dzv2V9Fh_V8ugFUxzftdmW5kq_KcfL._0023_003DzRw6ZUmZ68LAF2yi85xpB68sAa34J() ^ (int)(short)-~~--~-~~-~(995664381 ^ num1 ^ num2));
if ((Deobfuscate._0023_003DzorSRCcTOYKrh3x9df3y4zTUV7xtN & (Deobfuscate._0023_003Dz277oJx4nAbXTNVLUpThNrwpfFcLe) - ~~-~-~-~(-1146824238 - num1 - num2)) == (Deobfuscate._0023_003Dz277oJx4nAbXTNVLUpThNrwpfFcLe)0)
                Deobfuscate._0023_003Dz2gVGGuaOv4QwjTSyzGr7X5yxc453 = (-995626251 ^ num1) + num2;

int[] numArray = new int[4]
  {
    0,
    0,
    0,
    ~-~--~~-~-1863408518
  };

  numArray[1] = -~~--~-~~105240205;
  numArray[2] = -~~--~~-~-~445034824;
  numArray[0] = ~--~~--~~-~-393837398;
  int f6EjAc8IXjjzuWiO4 = this._0023_003Dz14FRLF6EjAC8_iXJjzuWiO4_003D;
  int tUvT87zJtuOmYrdE = this._0023_003Dzwdghyzouofs_0024tUVT87zJtuOmYRdE;
  int num1 = -~-~-~~-~1640531528;
  int num2 = -~~--~-~~957401313;

Take for example the following decompiled/obfuscated C# statement: int num2 = -~~--~-~~957401313;. What does it mean? C# does not recognize it as a valid statement, but indeed it's result of decompiling some IL code.

phuclv
  • 37,963
  • 15
  • 156
  • 475
usr-local-ΕΨΗΕΛΩΝ
  • 26,101
  • 30
  • 154
  • 305
  • 2
    The rules for valid identifiers in IL are broader that in C# - these may be valid IL identifiers that cannot be translated back into C# – Hans Kesting Jun 10 '21 at 15:25
  • 1
    If multiple negations are done, there should be parentheses to break them up, it's kind of bad that the decompiler didn't do that: `-~~-(-~-~~957401313)` – harold Jun 10 '21 at 15:25
  • As @HansKesting stated, ILs rules about variable names are a little more flexible than C#. Given that the code includes `Deobfuscate` it's likely been done on purpose to make it difficult to reverse engineer. – phuzi Jun 10 '21 at 15:29
  • @phuzi the `Deobfuscate` token is mine. I'm renaming every member manually once I found something meaningful. `Deobfuscate` is the root/goal element of my task – usr-local-ΕΨΗΕΛΩΝ Jun 10 '21 at 16:47

2 Answers2

1
  • - is just negation
  • ~ is bitwise NOT. Since C# requires two's complement integer representation, then ~x == -x - 1 for all X.
  • -- is the autodecrement operator, but it's only valid on lvalues, which numeric literals are not. I think this is a bug in the decompiler that forget to separate the minus signs.

So, a slightly de-obfuscated version of your last block of code is:

numArray[1] = -105240204;
numArray[2] = -445034826;
numArray[0] = 393837396;
int f6EjAc8IXjjzuWiO4 = this._0023_003Dz14FRLF6EjAC8_iXJjzuWiO4_003D;
int tUvT87zJtuOmYrdE = this._0023_003Dzwdghyzouofs_0024tUVT87zJtuOmYRdE;
int num1 = -1640531527;
int num2 = -957401312;
dan04
  • 87,747
  • 23
  • 163
  • 198
0

Here is how I break it up:

"~-~--~~-~-1863408518" (going from left to right)

1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 1110 1110 1010 0100 0111 1010 = -1863408518 
                                        0110 1111 0001 0001 0101 1011 1000 0101 (NOT)
1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 1110 1110 1010 0100 0111 1011 (-)
                                        0110 1111 0001 0001 0101 1011 1000 0100 (NOT)
1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 1110 1110 1010 0100 0111 1011 (NOT)
                                        0110 1111 0001 0001 0101 1011 1000 0101 (-)
1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 1110 1110 1010 0100 0111 1011 (-)
                                        0110 1111 0001 0001 0101 1011 1000 0100 (NOT)
1111 1111 1111 1111 1111 1111 1111 1111 1001 0000 1110 1110 1010 0100 0111 1100 (-)
                                        0110 1111 0001 0001 0101 1011 1000 0011 (NOT)

110 1111 0001 0001 0101 1011 1000 0011 = 1,863,408,515

SunsetQuest
  • 8,041
  • 2
  • 47
  • 42