Nanomites Technique from Nanomites.w32 Virus
2022-03-08 Dawid Farbaniec

The term nanomite is associated with a microscopic robot. This is also the name given to the known for a long time, but still used method against reverse code engineering (RCE). Technique is also used against easy rebuilding the code of the analyzed application from the process memory dump. In simple words, this technique main idea is to replace specific instructions (usually jumps -
For example, we want to change the program (.exe file) jump instruction
The implementations of this technique may vary. The standard scheme of operation is to replace the conditional jump instruction with the
Interception of an
The program in the main function sets the exception handler with the function
Educational example in x86-64 Assembly (MASM x64)
As mentioned before, this is only a simple educational example. In the case of a real implementation of this technique, it would definitely needed to add nanomite information structure encryption, separate the handler to other process and include other techniques for better protection.
JZ
, JNZ
, JC
etc.) in the Assembly language into INT 3h
interrupt commands defined as nanomites. During the execution of the program when hitting a nanomite, the control is transferred to a special procedure, which determines the further path of the code execution.
INT 3h
instructions are placed at the machine code level. When compiling the program, for example in C++, the various forms of code are C++, Assembly language, and finally machine code. An instruction in the Assembly language in text form (for example: INT
, MOV
, JNE
etc.) is called a mnemonic. On the other hand, the numerical value of an instruction in machine code is called operation code - abbreviated as: opcode.
For example, we want to change the program (.exe file) jump instruction
JNE
(Jump If Not Equal) to the instruction JE
(Jump If Equal). In the x64 architecture, the JNE
instruction has the 75h
opcode and the JE
instruction value is 74h
. These values can be found in the documentation of processors or in the various opcode lists available on the Internet. The change of the Assembly instruction in the .exe program can be made by changing the specific bytes in file or in memory (opcodes). For previously mentioned example, it is a change from 75h
to 74h
. The process of inserting nanomites to code is very similar. The opcode of a specific instruction is changed to INT 3h
nanomite with the opcode of 0CCh
.
The implementations of this technique may vary. The standard scheme of operation is to replace the conditional jump instruction with the
INT 3h
instruction (called a nanomite). When replacing opcodes, the program saves the type of jump (JE
, JNE
, JAE
etc.), the place where the jump instruction was (offset) and the place where the jump instruction leads (offset). This can be done for example by dividing the program into two processes: the control process and the process of the protected application. The controlling process would then have a procedure to handle the execution of the nanomite. For simplicity and easy learning there can be everything in one process. Main task is to recognize whether the INT 3h
interrupt is a nanomite or not. And then appropriate interrupt handling, for example: reading the previously saved type of jump, checking the state of the flag register and executing the jump, if the condition is met.
Interception of an
INT 3h
interrupt handler can be done in several ways. The first thing that comes to mind is Structured Exception Handling (SEH). One can also debug the created process (WaitForDebugEvent(...)
).
The program in the main function sets the exception handler with the function
SetUnhandledExceptionFilter(...)
. A simple comparison of the RAX register with some value (cmp rax, 02h
) is then performed. By default, after such a comparison there should be a conditional jump (eg JE
, JNE
etc.), but there is a nanomite. This is done with the nanomite_here
macro which takes two parameters: the jump type and the address to the target label. The macro writes the necessary information to the structure, and then raises an INT 3h
exception. Raising an exception passes control to the myExceptionHandler
routine. This procedure checks the type of jump, the condition based on the saved byte from the flag register, and decides whether to perform the jump, or whether it can pass control to the next instruction after INT 3h
.
Educational example in x86-64 Assembly (MASM x64)
;-------------------------------------------------+
; Nanomites anti-dump technique example ;
; (general idea, primitive educational prototype) ;
;-------------------------------------------------+
; Code: Dawid Farbaniec ;
;-------------------------------------------------+
extrn ExitProcess : proc
extrn MessageBoxA : proc
extrn SetUnhandledExceptionFilter : proc
;jump types
jumpTypeJZ equ 0
jumpTypeJNZ equ 1
jumpTypeJE equ jumpTypeJZ
jumpTypeJNE equ jumpTypeJNZ
;(...) etc.
;jump information structure
NanomiteStruct struct
JumpType dq ?
SavedFlags db ?
JumpAddress dq ?
NextInstructionAddress dq ?
NanomiteStruct ends
;create nanomite macro
nanomite_here macro _type, _address
lahf
mov nano.JumpType, _type
mov nano.SavedFlags, ah
mov rax, offset _address
mov nano.JumpAddress, rax
mov rax, offset @f
mov nano.NextInstructionAddress, rax
int 3h ;nanomite
@@:
endm
.data
szCaption db "ethical.blue", 0
szTextYes db "Nanomite executed.", 0
szTextNo db "Nanomite NOT executed.", 0
nano NanomiteStruct <0, 0, 0, 0>
.code
;this procedure is called by int 3h
myExceptionHandler proc
cmp nano.JumpType, jumpTypeJZ
jne @f
jmp _JZ
@@:
cmp nano.JumpType, jumpTypeJNZ
jne _return
_JNZ:
mov rcx, nano.JumpAddress
mov ah, nano.SavedFlags
and ah, 40h
cmp ah, 0h
jz _go
jmp _return
_JZ:
mov rcx, nano.JumpAddress
mov ah, nano.SavedFlags
and ah, 40h
cmp ah, 40h
jz _go
jmp _return
_go:
jmp rcx
jmp _return
_return:
jmp nano.NextInstructionAddress
myExceptionHandler endp
Main proc
sub rsp, 28h
mov rcx, myExceptionHandler
call SetUnhandledExceptionFilter
add rsp, 28h
mov rax, 07h
cmp rax, 02h
nanomite_here jumpTypeJNZ, _executed
jmp _notexecuted
_executed:
lea rdx, szTextYes
jmp _msgbox
_notexecuted:
lea rdx, szTextNo
_msgbox:
sub rsp, 28h
xor r9, r9
lea r8, szCaption
;RDX ustawiony wcześniej
xor rcx, rcx
call MessageBoxA
add rsp, 28h
_exit:
sub rsp, 28h
xor rcx, rcx
call ExitProcess
Main endp
end
As mentioned before, this is only a simple educational example. In the case of a real implementation of this technique, it would definitely needed to add nanomite information structure encryption, separate the handler to other process and include other techniques for better protection.