-
Автор темы
- #1
Aimware is one of the most long-lived projects on csgo cheating scene. It's known for its features and ...security, aimware hasn't been cracked for years. There were attempts, many of them, but not any actually succeeded until October 2021.
This superiority of aimware security comes from the unique techniques and implementations which honestly, I haven't seen ever before. As aimware is not the uncrackable project anymore I decided to share you some tricks it uses for education purposes.
1. Imports
If you're reading this article, you're probably aware of what imports are and how their references are implemented in some hacks, malwares etc. Well, the basic flow in any compiled PE binary is function -> IAT ptr call (via call/jmp dword) -> thus jump to the import address. Many hacks (e.g. ot and ft) use other technique: they find all references to IAT while mapping, then patching them to direct calls/jmps, but the problem is opcode length difference: call iat ptr opcode is 2 bytes length (FF 15) but direct (relative) call's opcode is only 1 byte (E8). In these hacks the problem is solved by adding a junk byte to the instruction, onetap uses 0x67 junk byte as a prologue to import call, fatality uses 0x90 which is nop instruction.
Aimware isahead of the game ahead of these hacks. All imports in aimwhere are being called by direct rets to them, the import value as well as return address (which is function_base + stub_start + stub_length) is pushed into the stack and then immediately returned. After import execution the jump appears which redirects us to random binary address where's function execution flow continues. In short, aimware imports abusing the stack and stubbing binary for small pieces which are randomly shuffled over it.
So, the jump is a single push (target) and the call is a double push (ret + target).
(a function with import reference inside)
2. Memory encryption
As you may know there's a table in every PE file called initterm which initializes some pointers, constants, predefined constructors etc before the dllmain is reached. There's such table in aimware as well but ... it's encrypted. Aimware uses unique identifier known as cpuid which is really reasonable since cpuid is a common processor instruction. So, the flow of each initterm function is: vtable reference -> stub which starts decryption loop -> decryption loop itself (xor'ing by cpuid values, rotating bits) -> jump to the decrypted function prologue -> after function is executed the encryption stub is called, here the functions is being crypted with rdtsc (instruction that returns time, it means that you won't be able to decrypt a function once it's executed unless you know each rdtsc value in crypt loop).
While bypassing this trick I came with the solution of patching all of cpuid references to ud2 (or int3, doesn't matter in this context) and then filling eax, ebx, ecx and edx registers with desired values.
(encrypted function, completely unreadable)
(decrypted function)
Nothing more?
Incorrect, aimware has a mutator implementation as well which means its binary is being randomly shuffled each time you load the hack. No possible way to find relocs ...at all.
There're also some security tricks (e.g. thread validation) but I think they are not that standing out as imports and memory encryption. If you want to analyze deeper and look how does the amazing custom security look like, go buy aimware the superior hack.
While analyzing aimware you probably will realize (as I did) how insignificant many of hacks are... They randomly use virtualization which leads to extremely long loading time (come and say "hi" to fatality) and which doesn't help them at all. For all young readers: virtualization is a strong and powerful obfuscation technique but it won't help you if you use it mindlessly.
This superiority of aimware security comes from the unique techniques and implementations which honestly, I haven't seen ever before. As aimware is not the uncrackable project anymore I decided to share you some tricks it uses for education purposes.
1. Imports
If you're reading this article, you're probably aware of what imports are and how their references are implemented in some hacks, malwares etc. Well, the basic flow in any compiled PE binary is function -> IAT ptr call (via call/jmp dword) -> thus jump to the import address. Many hacks (e.g. ot and ft) use other technique: they find all references to IAT while mapping, then patching them to direct calls/jmps, but the problem is opcode length difference: call iat ptr opcode is 2 bytes length (FF 15) but direct (relative) call's opcode is only 1 byte (E8). In these hacks the problem is solved by adding a junk byte to the instruction, onetap uses 0x67 junk byte as a prologue to import call, fatality uses 0x90 which is nop instruction.
Aimware is
So, the jump is a single push (target) and the call is a double push (ret + target).
(a function with import reference inside)
2. Memory encryption
As you may know there's a table in every PE file called initterm which initializes some pointers, constants, predefined constructors etc before the dllmain is reached. There's such table in aimware as well but ... it's encrypted. Aimware uses unique identifier known as cpuid which is really reasonable since cpuid is a common processor instruction. So, the flow of each initterm function is: vtable reference -> stub which starts decryption loop -> decryption loop itself (xor'ing by cpuid values, rotating bits) -> jump to the decrypted function prologue -> after function is executed the encryption stub is called, here the functions is being crypted with rdtsc (instruction that returns time, it means that you won't be able to decrypt a function once it's executed unless you know each rdtsc value in crypt loop).
While bypassing this trick I came with the solution of patching all of cpuid references to ud2 (or int3, doesn't matter in this context) and then filling eax, ebx, ecx and edx registers with desired values.
(encrypted function, completely unreadable)
(decrypted function)
Nothing more?
Incorrect, aimware has a mutator implementation as well which means its binary is being randomly shuffled each time you load the hack. No possible way to find relocs ...at all.
There're also some security tricks (e.g. thread validation) but I think they are not that standing out as imports and memory encryption. If you want to analyze deeper and look how does the amazing custom security look like, go buy aimware the superior hack.
While analyzing aimware you probably will realize (as I did) how insignificant many of hacks are... They randomly use virtualization which leads to extremely long loading time (come and say "hi" to fatality) and which doesn't help them at all. For all young readers: virtualization is a strong and powerful obfuscation technique but it won't help you if you use it mindlessly.