You are on page 1of 156

Theory of reverse engineering

Why

• Because AV doesn't work


• You should think as malware to find malware
• It’s awesome

2
Reverse engineering vs malware analysis

• You can use a huge amount of utilities and enterprise solutions, but there will come a day when
they don't help you.
• A reverse engineer can add utilities to his toolkit and use automatic solutions.
• A malware analyst will never be able to understand the malicious capabilities without
a reverse engineering if the sample bypasses analyst's tools.

3
I hope you know

• Difference between 0xDEAD and 57005


• Pointers in C++ or C
• EXE and DLL
• Functions, arguments, subfunctions
• for (int i=0; i<20; i++)
{}

4
Programming cycle

linker
• Source • Executable
code • Object file • Running
code process
compiler OS loader

5
Reverse engineering cycle

decompiler
•55 8B EC •void func {
•Push ebp
•Mov ebp
esp
disassembler

6
The code does not differ from the data

Disassembled code

Disassembled data

7
Constant or offset?

8
Little endian

• The lower byte is written at the smaller addresses!

9
Code or data?

10
Assembler as an instrument for reverse engineering

• You should know basic assembler instructions


• But you don’t have to know every command (Nobody analyzes tens of thousands of operations)
• It is important to be able to manage functions and their arguments
• The most difficult is math operations, but it’s not required for analysis in most cases
• We'll look at the most useful basic commands

11
Registers

Data Registers – EAX, EBX, ECX, EDX


Index Registers – ESI, EDI
Pointer Registers – EIP, ESP, EBP
Control Registers – one flag register
Segment Registers – CS, DS, SS

12
General-Purpose Registers

• Accumulator register (EAX). Used in arithmetic operations, also stored return value.
• Counter register (ECX). Used in shift/rotate instructions and loops.
• Data register (EDX). Used in arithmetic operations and I/O operations.
• Base register (EBX). Used as a pointer to data.
• Stack Pointer register (ESP). Pointer to the top of the stack.
• Stack Base Pointer register (EBP). Used to point to the base of the stack.
• Source Index register (ESI). Used as a pointer to a source in stream operations.
• Destination Index register (EDI). Used as a pointer to a destination in stream operations.

13
Instruction Pointer

• EIP - The EIP register contains the address of the next instruction to be executed if
no branching is done.

14
Stack Pointers

• ESP is the current stack pointer. EBP is the base pointer for the current stack frame.

15
EFLAGS

EFLAGS register holds many single bit flags. You should remember the following:

• Zero Flag (ZF) – Set of the result of some instruction is zero

• Sign Flag (SF) – Set equal to the most-significant bit of the result, which is the
sign bit of a single integer. (0 indicates a positive value and 1 indicates a negative value)

16
Instructions

• Usually consist of two parts: operation and arguments (operands)

operation
arguments

• Destination first

Move into EDI register offset of stru_B926D4

17
Operand types

• Registers: eax, ax, ebx


• Memory: [eax], offset stru_B90483
• Immediates: 0xB9
• Offset: [eax + 0x8]

18
Addressing Memory
• There is a difference between address of data and data (like pointers)
• Square brackets mean dereference

[0x00B8F416] = CharUpperW
Mov eax, 0x00B8F416 eax = 0x00B8F416
Mov eax, offset aCharupperw eax = 0x00B8F416
Mov eax, [0x00B8F416] eax = 0x43686172

ASCII
0x43 C
0x68 h
0x61 a
0x72 r
0x55 U
0x79 p

19
Basic instructions
• nop
• mov
• lea
• add, sub
• cmp
• test
• xor
• jmp, jz, jnz, je
• push/pop
• call
• ret
• leave

20
nop

• nop – no operation. Command that does nothing

• It’s very useful in RE for bytepatching, and gives


us the opportunity to skip any checks

21
mov

• mov – move. Copies data from one location to another


(from right to the left)
• mov eax, ebx
• mov eax, [0x0100FA35]
• mov eax, 0x4F
• mov [0x003F0033], ebx
• mov [0x00324424], [0x3f229304]

22
lea

• Lea – load effective address

• Move edx, [ebx + eax*8+4] edx stored data


• Lea edx, [ebx + eax*8+4] edx stored address

23
add sub

• Add – add
• Sub – substraction

Add eax, 1
Sub ebx, eax

24
cmp

• Cmp – compare. Compare operands and change flag register.

• This instruction basically subtracts one operand from the other for comparing
whether the operands are equal or not.
• It does not disturb the destination or source operands.
• It is used along with the conditional jump instruction for decision making.

• cmp eax, ecx


• cmp eax, 0x4f

25
test

• Test – logical compare

• Most commonly used to compare register with zero


• Test esi, esi (set ZF to 1 if esi ==0)

26
xor

• Xor – bitwise operation xor

• Most commonly used to setting the value of register to


zero
• xor esi, esi (esi ==0)

27
Jmp/jcc

Branching instructions
• jmp – unconditional jump
• jcc – conditional jumps
• jz – jump if zero
• je – jump if equal
• ja – jump if above
• jb – jump is below
• jnz – jump if not zero

28
Push/pop

Push - push a value onto the stack. Decrease ESP


value
Pop - pop data from stack. Increase ESP value

Push eax
Push 0x10
Pop eax

29
Call & Ret

Call – Call a procedure. Push EIP (return address)


Ret – Pop EIP. Jmp EIP

call ds:WriteFile
call sub_401887

ret
retn

30
Function prologue and epilogue

C++ ASM
void myfunc (void) push ebp
{ mov ebp, esp

} mov esp, ebp


pop ebp
ret

31
Functions

C++ ASM
void myfunc (void) push ebp
{ mov ebp, esp

} mov esp, ebp


pop ebp
ret

push ebp
void myfunc2 (void) mov ebp, esp
{ call myfunc
myfunc(); mov esp, ebp
} pop ebp
ret
32
Stack frame

A stack is a data structure that stores data in such


a way that the last piece of data stored, is the first
one retrived.
LIFO – Last In First Out

33
Passing arguments

34
Stack frame
myfunc:
push ebp
mov ebp, esp 0x00000000

mov esp, ebp


pop ebp
ret

ESP
myfunc2:
push ebp
mov ebp, esp
call myfunc
mov esp, ebp
pop ebp
ret 0xFFFFFFFF
35
Stack frame
myfunc:
myfunc:
push ebp
ebp
mov ebp,
ebp, esp
esp 0x00000000

mov
mov esp,
esp, ebp
ebp
pop
pop ebp
ebp
ret
ret
ESP
EBP (func2)
myfunc2:
myfunc2:
push ebp
push ebp
mov ebp, esp
mov ebp, esp
call myfunc
call myfunc
mov esp, ebp
mov esp, ebp
pop ebp
pop
ret ebp
ret 0xFFFFFFFF
36
Stack frame
myfunc:
myfunc:
push ebp
ebp
mov ebp,
ebp, esp
esp 0x00000000

mov
mov esp,
esp, ebp
ebp
pop
pop ebp
ebp
ret
ret
EBP ESP
EBP (func2)
myfunc2:
myfunc2:
push ebp
push ebp
mov ebp, esp
mov ebp, esp
call myfunc
call myfunc
mov esp, ebp
mov esp, ebp
pop ebp
pop
ret ebp
ret 0xFFFFFFFF
37
Stack frame
myfunc:
myfunc:
push ebp
ebp
mov ebp,
ebp, esp
esp 0x00000000

mov
mov esp,
esp, ebp
ebp
pop
pop ebp
ebp ESP
ret Return addr
ret
EBP
EBP (func2)
myfunc2:
myfunc2:
push ebp
push ebp
mov ebp, esp
mov ebp, esp
call myfunc
call myfunc
mov esp, ebp
mov esp, ebp
pop ebp
pop
ret ebp
ret 0xFFFFFFFF
38
Stack frame
myfunc:
myfunc:
push ebp
ebp
mov ebp,
ebp, esp
esp 0x00000000

mov esp, ESP


mov esp, ebp
ebp EBP (func)
pop
pop ebp
ebp
ret Return addr
ret
EBP
EBP (func2)
myfunc2:
myfunc2:
push ebp
push ebp
mov ebp, esp
mov ebp, esp
call myfunc
call myfunc
mov esp, ebp
mov esp, ebp
pop ebp
pop
ret ebp
ret 0xFFFFFFFF
39
Stack frame
myfunc:
myfunc:
push ebp
ebp
mov ebp,
ebp, esp
esp 0x00000000

mov esp, EBP ESP


mov esp, ebp
ebp EBP (func)
pop
pop ebp
ebp
ret Return addr
ret
EBP (func2)
myfunc2:
myfunc2:
push ebp
push ebp
mov ebp, esp
mov ebp, esp
call myfunc
call myfunc
mov esp, ebp
mov esp, ebp
pop ebp
pop
ret ebp
ret 0xFFFFFFFF
40
Stack frame
myfunc:
myfunc:
push ebp
ebp
mov ebp,
ebp, esp
esp 0x00000000

mov esp, EBP ESP


mov esp, ebp
ebp EBP (func)
pop
pop ebp
ebp
ret Return addr
ret
EBP (func2)
myfunc2:
myfunc2:
push ebp
push ebp
mov ebp, esp
mov ebp, esp
call myfunc
call myfunc
mov esp, ebp
mov esp, ebp
pop ebp
pop
ret ebp
ret 0xFFFFFFFF
41
Stack frame
myfunc:
myfunc:
push ebp
ebp
mov ebp,
ebp, esp
esp 0x00000000

mov
mov esp,
esp, ebp
ebp
pop
pop ebp
ebp ESP
ret Return addr
ret
EBP
EBP (func2)
myfunc2:
myfunc2:
push ebp
push ebp
mov ebp, esp
mov ebp, esp
call myfunc
call myfunc
mov esp, ebp
mov esp, ebp
pop ebp
pop
ret ebp
ret 0xFFFFFFFF
42
Stack frame
myfunc:
myfunc:
push ebp
ebp
mov ebp,
ebp, esp
esp 0x00000000

mov
mov esp,
esp, ebp
ebp
pop
pop ebp
ebp
ret
ret
EBP ESP
EBP (func2)
myfunc2:
myfunc2:
push ebp
push ebp
mov ebp, esp
mov ebp, esp
call myfunc
call myfunc
mov esp, ebp
mov esp, ebp
pop ebp
pop
ret ebp
ret 0xFFFFFFFF
43
Stack frame
myfunc:
myfunc:
push ebp
ebp
mov ebp,
ebp, esp
esp 0x00000000

mov
mov esp,
esp, ebp
ebp
pop
pop ebp
ebp
ret
ret
EBP ESP
EBP (func2)
myfunc2:
myfunc2:
push ebp
push ebp
mov ebp, esp
mov ebp, esp
call myfunc
call myfunc
mov esp, ebp
mov esp, ebp
pop ebp
pop
ret ebp
ret 0xFFFFFFFF
44
Stack frame
myfunc:
myfunc:
push ebp
ebp
mov ebp,
ebp, esp
esp 0x00000000

mov
mov esp,
esp, ebp
ebp
pop
pop ebp
ebp
ret
ret

ESP
myfunc2:
myfunc2:
push ebp
push ebp
mov ebp, esp
mov ebp, esp
call myfunc
call myfunc
mov esp, ebp
mov esp, ebp
pop ebp
pop
ret ebp
ret 0xFFFFFFFF
45
Return value
C++ ASM
int myfunc (void) myfunc:
{ push ebp
int a=0x10; mov ebp, esp
return a; sub esp, 4
} mov [ebp-4],0x10
mov eax, [ebp-4]
pop ebp
ret

46
Return value
myfunc:
push ebp
mov ebp, esp 0x00000000
sub esp, 4
mov [ebp-4],0x10
mov eax, [ebp-4]
mov esp, ebp
pop ebp
ret EBP ESP
EBP v1.0

0xFFFFFFFF
47
Return value
myfunc:
push ebp
mov ebp, esp 0x00000000
sub esp, 4
mov [ebp-4],0x10
mov eax, [ebp-4]
mov esp, ebp
ESP
pop ebp
ret EBP
EBP v1.0

0xFFFFFFFF
48
Return value
myfunc:
push ebp
mov ebp, esp 0x00000000
sub esp, 4
mov [ebp-4],0x10
mov eax, [ebp-4]
mov esp, ebp ESP
pop ebp 0x00000010
ret EBP
EBP v1.0

0xFFFFFFFF
49
Return value
myfunc:
push ebp
mov ebp, esp 0x00000000
sub esp, 4
mov [ebp-4],0x10
mov eax, [ebp-4]
mov esp, ebp ESP
pop ebp 0x00000010
ret EBP
EBP v1.0

0xFFFFFFFF
50
Return value
myfunc:
push ebp
mov ebp, esp 0x00000000
sub esp, 4
mov [ebp-4],0x10
mov eax, [ebp-4]
mov esp, ebp
pop ebp
ret EBP ESP
EBP v1.0

0xFFFFFFFF
51
Return value
myfunc:
push ebp
mov ebp, esp 0x00000000
sub esp, 4
mov [ebp-4],0x10
mov eax, [ebp-4]
mov esp, ebp
pop ebp
ret
ESP

0xFFFFFFFF
52
Passing arguments
myfunc:
push ebp
int myfunc (int b) mov ebp, esp
{ sub esp, 4
int a=0x10; mov [ebp-4],0x10
return a+b; mov eax, [ebp-4]
} mov edx, [ebp+8]
add eax, edx
mov esp, ebp
pop ebp
ret

myfunc2:
push ebp
int myfunc2 (void) mov ebp, esp
{ push 8
myfunc(8); call myfunc
} mov esp, ebp
pop ebp
53
ret
Passing arguments
myfunc2:
push ebp
mov ebp, esp
push 8
call myfunc
mov esp, ebp
pop ebp
ret
EBP ESP
EBP v1.0

0xFFFFFFFF
54
Passing arguments
myfunc2:
push ebp
mov ebp, esp
push 8
call myfunc
mov esp, ebp
pop ebp ESP
ret 0x00000008
EBP
EBP v1.0

0xFFFFFFFF
55
Passing arguments
myfunc:
push ebp
mov ebp, esp
sub esp, 4
mov [ebp-4],0x10
mov eax, [ebp-4] ESP
Return addr
mov edx, [ebp+8]
add eax, edx 0x00000008
mov esp, ebp EBP
EBP v1.0
pop ebp
ret

0xFFFFFFFF
56
Passing arguments
myfunc:
push ebp
mov ebp, esp
sub esp, 4 ESP
mov [ebp-4],0x10 EBP v2.0
mov eax, [ebp-4] Return addr
mov edx, [ebp+8]
add eax, edx 0x00000008
mov esp, ebp EBP
EBP v1.0
pop ebp
ret

0xFFFFFFFF
57
Passing arguments
myfunc:
push ebp
mov ebp, esp
sub esp, 4 EBP ESP
mov [ebp-4],0x10 EBP v2.0
mov eax, [ebp-4] Return addr
mov edx, [ebp+8]
add eax, edx 0x00000008
mov esp, ebp
EBP v1.0
pop ebp
ret

0xFFFFFFFF
58
Passing arguments
myfunc:
push ebp
mov ebp, esp ESP
sub esp, 4 EBP
mov [ebp-4],0x10 EBP v2.0
mov eax, [ebp-4] Return addr
mov edx, [ebp+8]
add eax, edx 0x00000008
mov esp, ebp
EBP v1.0
pop ebp
ret

0xFFFFFFFF
59
Passing arguments
myfunc:
push ebp
mov ebp, esp ESP
0x00000010
sub esp, 4 EBP
mov [ebp-4],0x10 EBP v2.0
mov eax, [ebp-4] Return addr
mov edx, [ebp+8]
add eax, edx 0x00000008
mov esp, ebp
EBP v1.0
pop ebp
ret

0xFFFFFFFF
60
Passing arguments
myfunc:
push ebp
ESP
mov ebp, esp 0x00000010
sub esp, 4 EBP
mov [ebp-4],0x10 EBP v2.0
mov eax, [ebp-4] Return addr
mov edx, [ebp+8]
add eax, edx 0x00000008
mov esp, ebp
EBP v1.0
pop ebp
ret

0xFFFFFFFF
61
Passing arguments
myfunc:
push ebp
ESP
mov ebp, esp 0x00000010
sub esp, 4 EBP
mov [ebp-4],0x10 EBP v2.0
mov eax, [ebp-4] Return addr
mov edx, [ebp+8]
add eax, edx 0x00000008
mov esp, ebp
EBP v1.0
pop ebp
ret

0xFFFFFFFF
62
Passing arguments
myfunc:
push ebp
mov ebp, esp ESP
0x00000010
sub esp, 4 EBP
mov [ebp-4],0x10 EBP v2.0
mov eax, [ebp-4] Return addr
mov edx, [ebp+8]
add eax, edx 0x00000008
mov esp, ebp
EBP v1.0
pop ebp
ret

0xFFFFFFFF
63
Passing arguments
myfunc:
push ebp
mov ebp, esp
sub esp, 4 EBP ESP
mov [ebp-4],0x10 EBP v2.0
mov eax, [ebp-4] Return addr
mov edx, [ebp+8]
add eax, edx 0x00000008
mov esp, ebp
EBP v1.0
pop ebp
ret

0xFFFFFFFF
64
Passing arguments
myfunc:
push ebp
mov ebp, esp
sub esp, 4
mov [ebp-4],0x10
mov eax, [ebp-4] ESP
Return addr
mov edx, [ebp+8]
add eax, edx 0x00000008
mov esp, ebp EBP
EBP v1.0
pop ebp
ret

0xFFFFFFFF
65
Passing arguments
myfunc2:
push ebp
mov ebp, esp
push 8
call myfunc
mov esp, ebp
pop ebp ESP
ret 0x00000008
EBP
EBP v1.0

0xFFFFFFFF
66
Passing arguments
myfunc2:
push ebp
mov ebp, esp
push 8
call myfunc
mov esp, ebp
pop ebp
ret
EBP ESP
EBP v1.0

0xFFFFFFFF
67
Passing arguments
myfunc2:
push ebp
mov ebp, esp
push 8
call myfunc
mov esp, ebp
pop ebp
ret

ESP

0xFFFFFFFF
68
If then

C++ ASM
int ReturnMax(int a, int b)
{ mov eax, [ebp+arg_0]
if (a>b) cmp eax, [ebp+arg_4]
return a; jle short loc_4122DD
else mov eax, [ebp+arg_0]
return b; jmp short loc_4122E0
}
loc_4122DD:
mov eax, [ebp+arg_4]

loc_4122E0:
...
ret

69
Case switch

C++ ASM
char * DoSwitch(int MyNumber) mov ecx, [ebp+arg_0]
{ sub ecx, 1
char * result; cmp ecx, 4
switch (MyNumber) ja short loc_4132F7
{ jmp ds:off_413308[ecx*4]

case 1: loc_4132DC:
result="one"; mov [ebp+var_8], offset aOne
break; jmp short loc_4132FE
case 2: loc_4132E5:
result="two"; mov [ebp+var_8], offset aTwo
break; jmp short loc_4132FE
case 3: loc_4132EE:
case 4: mov [ebp+var_8], offset aMany
case 5: jmp short loc_4132FE
result="many"; loc_4132F7:
break; mov [ebp+var_8], offset aDonTKnow
default: loc_4132FE:
result="don't know"; mov eax, [ebp+var_8]
}
return result; off_413308 dd offset loc_4132DC
} dd offset loc_4132E5
dd offset loc_4132EE
dd offset loc_4132EE
dd offset loc_4132EE

70
Prologue

int main()
{
char buf[100];
printf("Input your string:\n");
scanf("%s", &buf);
if (strlen(buf) <= 5)
printf("Too short\n");
else
printf("%s\n", buf);
return 0
}

71
Assignment

int main()
{
char buf[100];
printf("Input your string:\n");
scanf("%s", &buf);
if (strlen(buf) <= 5)
printf("Too short\n");
else
printf("%s\n", buf);
return 0
}

72
Branching

int main()
{
char buf[100];
printf("Input your string:\n");
scanf("%s", &buf);
if (strlen(buf) <= 5)
printf("Too short\n");
else
printf("%s\n", buf);
return 0
}

73
Call

int main()
{
char buf[100];
printf("Input your string:\n");
scanf("%s", &buf);
if (strlen(buf) <= 5)
printf("Too short\n");
else
printf("%s\n", buf);
return 0
}

74
Epilogue

int main()
{
char buf[100];
printf("Input your string:\n");
scanf("%s", &buf);
if (strlen(buf) <= 5)
printf("Too short\n");
else
printf("%s\n", buf);
return 0
}

75
Call
Assigment Calls

push offset Format ; "Input your string:\n"


Sub esp, 100 call ds:printf
add esp, 4

lea eax, [ebp+Str]


push eax
push offset aS ; "%s"
Prologue call ds:scanf Epilogue
add esp, 8

lea ecx, [ebp+Str]


push ecx ; Str
call strlen xor eax, eax
push ebp add esp, 4 mov esp, ebp
mov ebp, esp pop ebp
retn
Branching push offset aTooShort ; "Too short\n"
call ds:printf
add esp, 4

lea edx, [ebp+Str]


cmp eax, 5 push edx
ja short loc_401047 push offset aS_0 ; "%s\n"
call ds:printf
add esp, 8
76
làm thế nào để vẽ một con cú
Practice time

• Open the directory “day1”

• Open the directory “Asm”

• Try to understand the functionality

78
v1

79
v1

Hex Rays

Source code

80
v2
v2
Hex Rays Source code

82
v3

83
v3
Hex Rays Source code

84
v4

85
v4

Hex Rays Source code

86
v5

87
v5

Hex Rays Source code

88
PE format

89
File Header

90
Optional Header

91
Section headers

92
Export directory

93
Import directory

94
Resource editor

95
Most important things in PE

PE signature
• MZ (4D 5A)

DOS STUB
• “This program cannot be run in MS-DOS mode.”

TimeDateStamp
• The time that the linker produced this file

ImageBase
• When the linker creates an executable, it assumes that the file will be memory-mapped to a specific location in memory. Default base address for Win32 executables is
0x400000
AddressOfEntryPoint
• the address where the loader will begin execution

Section headers
• they should be repaired for correct dumping

96
Import table

97
Malware functions

You don’t have to analyze every assembler command!

There are common api sequences you should


remember

98
Using MSDN

99
Understanding WinApi

100
Understanding WinApi

101
Understanding WinApi

102
Handles

The application cannot use system resources directly, so it needs to get


special «handle»
Handle is an abstract reference value to a resource, object, or an open file,
or a pipe.
It’s obtained through Api and used in Api

103
Handles

104
Return Value

105
Creating new threads

• CreateThread - Creates a thread to execute within the


virtual address space of the calling process.

• StartAddress
• Sub_402530
• Sub_404030

106
Creating new threads
• SetThreadPriority - sets the priority value for the specified thread.
This value, together with the priority class of the thread's process,
determines the thread's base priority level.

107
Working with registry

RegCreateKeyW - Creates the specified registry key.


If the key already exists, the function opens it.

• HKEY_CURRENT_USER\\Software\\0

108
Set registry value

• RegSetValueEx - Sets the data and type of a


specified value under a registry key.

109
Delete registry key
• RegDeleteKeyA - Deletes a subkey and its values. Note that key
names are not case sensitive.

110
Find Files
• FindFirstFile - Searches a directory for a file or
subdirectory with a name that matches a specific
name
• FindNextFile - Continues a file search from a
previous call to the FindFirstFile
• FindClose - Closes a file search handle opened by
the FindFirstFile

111
Reading Files
• CreateFileW - Creates or opens a file or I/O
device. The function returns a handle that can
be used to access the file or device for various
types.

• GetFileSize - Retrieves the size of the specified


file, in bytes.

• LocalAlloc - Allocates the specified number of


bytes from the heap.

• ReadFile - Reads data from the specified file or


input/output (I/O) device.

• CloseHandle - Closes an open object handle.

112
Writing files

• WriteFile - Writes data to the specified file or


input/output (I/O) device.

113
Get functions

GetModuleHandle - Retrieves a module


handle for the specified module. The
module must have been loaded by the
calling process.

GetProcAddress - Retrieves the address


of an exported function or variable from
the specified dynamic-link library (DLL).

114
Sleeping

• Sleep - Suspends the execution of the current


thread until the time-out interval elapses.

115
Sockets
• Socket - creates a socket that is bound to a specific
transport service provider. Af = 2, so it is The Internet
Protocol version 4 (IPv4) address family.

• htons - converts a u_short from host to TCP/IP network


byte order. 0x1BB -> 0xBB01
1BB in hex means 443 in dec

• connect - establishes a connection to a specified socket.

• send - sends data on a connected socket.

116
Socket structure

117
Api hooks

Manipulate
Rootkits
application Self spreading
activities
data

Stealing
Persistence
credentials

118
Api hooking (splicing)

VirtualProtect() WriteProcessMemory()
• Get address of • Save first bytes • Restore original
function • Set memory of function • Overwrite first permissions
permissions to bytes to jmp
read/write <offset
handler>
GetProcAddress() ReadProcessMemory() VirtualProtect()

119
Api hooks

plaintext

Windows
Call CryptEncrypt
CryptEncrypt
ciphertext

120
Api hooks (splicing)

Store Data
(evil code)

plaintext
Call windows
CryptEncrypt CryptEncrypt

Jmp to evil
code

121
Find hooks

122
Hooks handlers

123
Inject techniques

Hide Get
malicious application
code data

Set hooks Bypass AV

Persistance

124
Classic injection

VirtualAllocEx CreateRemoteThread()
• Get handle to • Write payload
target process • Allocate a new into target • Start a new
chunk of process as thread
memory in separate RWE
target process
OpenProcess() WriteProcessMemory

125
DLL injection

VirtualAllocEx() GetProcAddress()
• Take handle to • Write DLL name • Instruct the target
target process of DLL path into process to
• Allocate a new allocated chunk • Find address of LoadLibraryA()
chunk of memory LoadLibraryA() malicious DLL
in target process

OpenProcess() WriteProcessMemory() CreateRemoteThread()

126
DLL hijacking

Based on searching order of DLL


• a) current working directory of the application, highest priority, first check
• b) \windows
• c) \windows\system32

Place a malicious DLL into working directory with the same name as DLL used by the application

Make sure that the malicious DLL can run functions from the original to prevent the application
from crashing

127
Process Hollowing

At launch, the legitimate process is


created in a suspended state and the
Sometimes there is no suspicious RWE
process’s memory is replaced with the
sections in process memory, so it is
code of a second program so that the
harder to detect malware.
second program runs instead of the
original program.

128
Process Hollowing

WriteProcessMemory() ResumeThread()
• Create • Set up
suspended • Write payload execution • Resume process
process instead of with malicious
original process code
code
CreateProcessW() SetThreadContext()

129
Process Hollowing

130
Process Hollowing

131
Reflective DLL Injectoin

Special function that maps dll into memory -> ReflectiveLoader

Volatility cannot find injected dll via dlllist

Very common technique (meterpreter, cobalt strike, powershell empire)

https://github.com/stephenfewer/ReflectiveDLLInjection
132
Reflective DLL Injectoin

Write dll into target process in any way

Call ReflectiveLoader()

133
Reflective DLL Injection

134
Persistence via registry

HKLM\SOFTWARE\Microsoft\Windows
NT\Current Version\Windows\Appinit_Dlls

• All the DLLs that are specified in this value are


loaded by each Microsoft Windows-based
application that is running in the current log on
session.

135
Process memory structure

136
RWE sections

137
RWE sections

138
Protected malware

Avoid Increasing Protect from


detection analyze time patching

139
Packers

• Imagine one executable file inside another executable file.


• When executed, the special code named “stub” will unpack compressed
part and execute it.

140
Packers
Original executable before packing Unpacked executable in memory

PE Header PE Header

Exports Packed executable Exports


Start address
Imports PE Header .data section
Start address
.data section Unpacking stub
.text section
Start address

.text section Packed .rdata section


Packing original code Unpacking
.rdata section .rsrc section

.rsrc section Imports

Compressed and encrypted

All strings and code are visible Back to clear text


(clear text)

141
Protected malware
Packed EP Unpacked EP

142
Protected malware

Packed Unpacked

143
Protected malware

Packed

Unpacked

144
Self modified code

145
Encrypted strings

146
Anti-debug tricks

147
Anti-VM tricks

148
Anti-VM tricks

149
Anti-sandbox tricks

150
Api hash

151
Hidden configuration files

Read encrypted
Take C&C from
config from Decrypt config
config
registry

152
Encrypted payload

Stub reads special It uses it to


Pass the execution
hardware decrypt the
to the payload
parameters encrypted payload

153
Сheck availability of the Internet

Http request Or pass the


Exit if no
to execution to
response
“google.com” the payload

154
Сheck Internet history

Search Or pass the


Exit if no
“bank.com” in execution to
matches
IE history the payload

155
Trifonov Vitalii
trifonov@group-ib.com

www.group-ib.ru info@group-ib.ru twitter.com/groupib


blog.group-ib.ru +7 495 984 33 64 facebook.com/group-ib

You might also like