90

The .so file is a compiled library, in most cases from C or C++ source code. .so stands for Shared Object, it doesn't have anything to do with obfusation, it just means someone wrote parts of the app in C. In some cases, there is existing C code and it's just easier for the programmer to build a JNI interface to call the library from java; in other cases, ...


47

This is for position independent code. The call 0xe50b instruction pushes the address of the next instruction, and then jumps. It jumps to the immediately following instruction, which has no effect. The next instruction, pop eax, loads its own address into eax (as it was the value pushed by call). Further down it uses an offset from eax: mov eax, dword [ds:...


28

The paper Static Analysis of x86 Executables explains overlapping instructions quite well. The following example is taken from it (page 28): 0000: B8 00 03 C1 BB mov eax, 0xBBC10300 0005: B9 00 00 00 05 mov ecx, 0x05000000 000A: 03 C1 add eax, ecx 000C: EB F4 jmp $-10 000E: 03 C3 add eax, ebx 0010: C3 ret By ...


24

From this paper by Timea Laszlo and Akos Kiss : The basic method for flattening a function is the following. First, we break up the body of the function to basic blocks, and then we put all these blocks, which were originally at different nesting levels, next to each other. The now equal-leveled basic blocks are encapsulated in a selective structure (a switch ...


24

Besides Guntram's suggestions, check out the retargetable decompiler aka retdec. It can decompile the binary to Python or C code. At least for me, it reads easier than pure assembly (and it works for ARM binaries). It works very well for sketching you the rough workings of the shared object. A plugin for select IDA versions exists, but the main limitation ...


23

There are a few tools that you might try when wanting to analyze JavaScript: JSDetox Malzilla JavaScript Deobfuscator ExtractScript JS-Beautifier JS-Unpack (see also blog) Rhino Debugger Firebug SpiderMonkey V8 JSNice PoisonJS See also a few tutorials on analyzing obfuscated JavaScript: Analyzing Malicious JavaScript by Dejan Lukan. Advanced obfuscated ...


22

I've been dissecting the firmware for another type of embedded device for a while and thought I'd see if I could find anything out. After a few hours I figured it out! There is a hard way and an easy way that I found only after digging the hard way. This is a long post, but I hope it will help others in similar ventures. A little Googling and I found ...


19

An opaque predicate is an obfuscated condition, that, followed with a conditional operation, will make the analysis harder, and in some cases impossible until code is actually executed until that condition is evaluated. This is used to disrupt static analysis (outcome is unpredictable) or emulation (to tell the difference between a real machine and an ...


19

The answers already in this thread are good ones. In a nutshell, an opaque predicate is "something that a program analysis might miss, if the program analysis is not sophisticated enough". Denis' example was based on the inverse of constant propagation, and served as an anti-checksum mechanism. Joxean's SetErrorMode example was an environment-based opaque ...


19

Here are tricks you can use when packaging your python app with a custom interpreter. Remap the opcodes for the interpreter Encrypt the pyc files (the custom interpreter decrypts before importing) Remove access to co_code in the interpreter (delete the reference to co_code in the code_memberlist array declaration in codeobject.c of the interpreter) ...


19

For a good example of this obfuscation, check Apple's FairPlay code, e.g. iTunes or iOS libs. Here's a typical graph of a function which had this obfuscation applied: As you can see, all edges between basic blocks - both conditional and unconditional - has been redirected to a dispatcher node which uses a new artificial variable to decide which block should ...


17

virtualizers usage in the wild They are rarely used, and even worse (or better), rarely used in a useful way. how they're used Typically, it was the use of a virtualizer of over only the main function, or another binary packer, and both cases don't prevent analysis: if you bypass the virtualized packer code, then you get the original unpacked code anyway. ...


17

Generic definition Binary packers alter the original binary data, and restore it (more or less) before execution. Their different names depend more on their characteristic: it's difficult to clearly distinguish, as just putting an anti-debug and a Xor loop would make a packer also a protector and a cryptor. types extension extra packer code is executed ...


16

This is a frequently used "trick" to determine the address of the instruction following the call, i.e. the call instruction pushes the return address on the stack, which in this case corresponds to 0xe50b. After the pop instruction, eax contains that address. For instance, this idiom is used for position independent code (pic), but is also quite commonly ...


16

It's also known as the 'jump in the middle' trick. explanation execution rules most instructions take more than one byte to be encoded they can take up to 15 bytes on modern CPUs execution can start at any position as long as permissions are valid so any byte following the first one of an instruction can be re-used to start another instruction. ...


16

These techniques of mutating code (and still keeping it semantically equivalent) are known as polymorphic code. The software that can achieve a mutations of the code is usually called a polymorphic engine. It is a quite widely used technique in Malware design to evade pattern-matching detection of the anti-virus software. With these key words in hand (and ...


15

Using Malzilla, I was able to de-obfuscate this in ~30 seconds. Step 1, open Malzilla, select the Decoder tab, and paste the JavaScript. Step 2, you can optionally press the "Format Code" button to get a rudimentary re-formatting of the JS. Step 3, check Override eval(), and click the Run script button. You'll notice that in the output box, the de-...


14

Now I cannot possibly know what the exact reason is here, but there is another very good reason, not mentioned so far, for using this kind of method: throwing off a disassembler during static analysis. The mechanics of call $+5 have been discussed, so I'll assume they are known by now - otherwise refer to the other answers. Basically like with any call on ...


12

Not necessarily the predicate must be hard to evaluate. An opaque predicate is a condition which the result is known in advance by the programmer and that cannot be resolved statically (by a compiler, for example) and must be resolved dynamically. An example I noticed in malware some years ago: SetErrorMode(100); if ( SetErrorMode(1024) == 100 ) // ...


12

You can also try a dynamic approach by hooking APIs and observing arguments and return values. This will allow you to look at data going into crypto APIs, which may help a lot when dealing with network protocols. Check out the Frida instrumentation toolkit for an open source cross-platform solution (Android, iOS, Windows, Mac and Linux). There's a tutorial ...


11

Instruction camouflage is an obfuscation technique against simple naive static analysis of the binary. The binary program is composed of two parts: A decoder An encoded payload When executed, the binary first goes to the decoder and decode the payload that unveil the real assembly code. At the end, the decoder jumps to the decoded payload and execute the ...


11

A CALL instruction has the effect of pushing a return address onto the stack, before performing the control transfer to the call target. In your example above, the CALL instruction will push the value 0x0000E50B onto the stack, before transferring control to 0x0000E50B. The POP instruction at 0x0000E50B will then pop the last value off of the top of the ...


11

Why limit yourself to static deobfuscation? If you run that script through a JavaScript debugger and break on the return statement, you can see that _0xf81fx1 = function myFunction(){var x=5;return x}, which was the plain-text of the function before it was obfuscated. Furthermore, if you run it through http://jsbeautifier.org, the last line of the output is:...


11

The numbers in the third column do increase over time, which is a good start. Let's check the differences between numbers on consecutive lines, to see if the progression is linear: #!/usr/bin/env python import re, sys, time lines = sys.stdin.readlines() def parse(l): return time.mktime(map(int,l[0:6]) + [0]*3), int(l[6], 16) stamps = [parse(re.split('[\n.: ]...


11

Use android-ndk, https://developer.android.com/ndk/downloads/index.html. You can use the toolchains inside the ndk to perform the type of disassembling you want to. For e.g. if I decompile an apk and get a .so library out of it, I will do : ./android-ndk-r15b/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-objdump -T "...


10

There are three main contributions of the research A proposed indistinguishability obfuscation for NC1 circuits where the security is based on the so called Multilinear Jigsaw Puzzles (a simplified variant of multilinear maps). Pair the contribution in 1 with Fully Homomorphic Encryption and you get indistinguishability obfuscation for all circuits. Combine ...


9

Sort of it also can be found in malicious obfuscated JavaScript code: 001 vz = 1; 002 var1 = 49; 003 var2 = var1; 004 if (var1 == var2){ 005 document.location = "http://path.to.malicious.website"; 006 } here You see attempt in line 001-004 declare vars and conditions, that meaningless, and present to change obfuscated code hash ...


9

Definition We'll define a packer as an executable compressor. Packers reduce the physical size of an executable by compressing it. A decompression stub is usually then attached, parasitically, to the executable. At runtime, the decompression stub expands the original application and transfers control to the original entry point. Packers exist for almost ...


9

Most tools don't support a 'ignore that byte for disassembly' feature, only IDA, Hopper and a few others do. The only alternative is to patch the byte at 8049444 with a 90 NOP, or change your mind and not rely on basic tools.


9

I would start with not have critical strings in memory in linear manner Instead each character can be offseted by some offset like by table mixing all the strings together. For example you got 0123456789 if you store them in memory like this: |0x1xx2xxx3xxxx4| |xxxxx5xxxxxx6xx| |xxxx7xxxxxxxx8x| |xxxxxxxx9xxxxxx| where x is anything or another string ... ...


Only top voted, non community-wiki answers of a minimum length are eligible