⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 29a-7.019

📁 从29A上收集的病毒源码
💻 019
📖 第 1 页 / 共 4 页
字号:
dd -1                   ; C7
dd 0                    ; C8
dd 0                    ; C9
dd 0                    ; CA
dd 0                    ; CB
dd 0                    ; CC
dd 0                    ; CD
dd 0                    ; CE
dd 0                    ; CF
dd -1                   ; D0
dd -1                   ; D1
dd -1                   ; D2
dd -1                   ; D3
dd -1                   ; D4
dd -1                   ; D5
dd -1                   ; D6
dd -1                   ; D7
dd -1                   ; D8
dd -1                   ; D9
dd -1                   ; DA
dd -1                   ; DB
dd -1                   ; DC
dd -1                   ; DD
dd -1                   ; DE
dd -1                   ; DF
dd -1                   ; E0
dd -1                   ; E1
dd -1                   ; E2
dd -1                   ; E3
dd -1                   ; E4
dd -1                   ; E5
dd -1                   ; E6
dd -1                   ; E7
dd -1                   ; E8
dd -1                   ; E9
dd -1                   ; EA
dd -1                   ; EB
dd -1                   ; EC
dd -1                   ; ED
dd -1                   ; EE
dd -1                   ; EF
dd -1                   ; F0
dd -1                   ; F1
dd -1                   ; F2
dd -1                   ; F3
dd -1                   ; F4
dd -1                   ; F5
dd -1                   ; F6
dd -1                   ; F7
dd -1                   ; F8
dd -1                   ; F9
dd -1                   ; FA
dd -1                   ; FB
dd -1                   ; FC
dd -1                   ; FD
dd -1                   ; FE
dd -1                   ; FF

                        end


	Now we are able to get instruction length on arbitrary address. We will
repeat this call until 5 bytes are read. After this we will copy these bytes 
to old_hook. We know how long are first instructions, so we can fill out the 
relative jump address on the next instruction in original function.

.386p
.model flat, stdcall

...

.data

 kernel_name 		db "kernel32.dll",0
 sleep_name		db "Sleep",0

 ...

 MEM_RELEASE		dd 000008000h

;16 nops + one relative jump
 old_sleep		db 090h,090h,090h,090h,090h,090h,090h,090h,
			   090h,090h,090h,090h,090h,090h,090h,090h,
			   0E9h,000h,000h,000h,000h


.code
start:
	push	5000
	call	Sleep

 do_hook:
	push	offset kernel_name
	call	GetModuleHandleA
	push	offset sleep_name
		push	eax
	call	GetProcAddress
        push	eax
	mov	esi,eax

	xor	ecx,ecx
	mov	ebx,esi
 get_five_bytes:
	push    ecx
	push	ebx
	call	get_instr_len		;calling LDE32
	pop	ecx
	add	ecx,eax
	add	ebx,eax
	cmp	ecx,5
	jb	get_five_bytes
	mov	edi,offset old_sleep	;counting relative jump address
	mov	[edi+011h],ebx
	sub	[edi+011h],edi
	sub	dword ptr [edi+011h],015h
	rep	movsb
	pop	edi

;following code was above, so without comments

	push	PAGE_READWRITE
	push	MEM_COMMIT
	push	MEMORY_BASIC_INFORMATION_SIZE
	push 	0
	call	VirtualAlloc
	test	eax,eax
	jz 	do_sleep
	mov	esi,eax

	push	MEMORY_BASIC_INFORMATION_SIZE
	push	esi
	push	edi
	call	VirtualQuery
	test	eax,eax
	jz	free_mem

	call	GetCurrentProcess
	push	5
	push	edi
	push	eax
	call	FlushInstructionCache	

	lea	eax,[esi+014h]
	push	eax
	push	PAGE_EXECUTE_READWRITE
	lea	eax,[esi+00Ch]
	push	[eax]
	push	[esi]
	call	VirtualProtect
	test	eax,eax
	jz	free_mem

	mov	byte ptr [edi],0E9h
	mov	eax,offset new_sleep
	sub	eax,edi
	sub	eax,5
	inc	edi
	stosd

	push	offset old_protect
	lea	eax,[esi+014h]
	push	[eax]
	lea	eax,[esi+00Ch]
	push	[eax]
	push	[esi]
	call	VirtualProtect

 free_mem:
	push	MEM_RELEASE
	push	0
	push	esi
	call	VirtualFree
 do_sleep:
	push	5000
	call	Sleep
	push	0
	call	ExitProcess
 new_sleep:
	mov	eax,dword ptr [esp+004h]		
	add	eax,eax				;doubling timeout
	push	eax
	mov	eax,offset old_sleep            ;calling old function 
	call	eax
	ret	004h



After the hook it will look like this: 

	004010CC: 6888130000	push 000001388h
	004010D1: E818090000	call Sleep


	Sleep:     ;this is jump on address in IAT 
	004019EE: FF2514204000	jmp dword ptr [000402014h]
 
	tabulka:
	00402014: 79 67 E8 77 6C 7D E8 77
      
	Kernel32.Sleep:
	77E86779: E95FA95788	jmp 0004010DDh

	new_sleep:
	004010DD: 8B442404	mov eax,dword ptr [esp+4]
	004010E1: 03C0		add eax,eax
	004010E3: 50		push eax
	004010E4: B827304000	mov eax,000403027h
	004010E9: FFD0		call eax

	old_sleep:
	00403027: 6A00		push 0
	00403029: FF742408	push dword ptr [esp+8]
	0040302D: 90		nop
	0040302E: 90		nop
	0040302F: 90		nop
	00403030: 90		nop
	00403031: 90		nop
	00403032: 90		nop
	00403033: 90		nop
	00403034: 90		nop
	00403035: 90		nop
	00403036: 90		nop
	00403037: E94337A877	jmp Kernel32.77E8677F

;this instruction is placed 1 byte after first instruction at Kernel32.Sleep 
(77E86779)

	Kernel32.77E8677F:	
	77E8677F: E803000000	call Kernel32.SleepEx
	...			;following is unimportant

To make this clearer, this is how the original version of Kernel32.Sleep looks:

	Kernel32.Sleep:
	77E86779: 6A00		push 0
	77E8677B: FF742408	push dword ptr [esp+8]
	77E8677F: E803000000	call Kernel32.SleepEx
	77E86784: C20400	ret 00004h


	As you can see we copied first and second instruction (it was 6 bytes
here) and the relative jump pointed on the next instruction and that is how 
it should be. We have to supposed here that relative jumps are not placed 
as the first bytes of functions. If there would be we've got a problem. Next 
problem is with APIs like ntdll.DbgBreakPoint. These are too short for this 
method of hooking. And forasmuch as it is called by Kernel32.DebugBreak, it is 
not hookable by changing IAT. But who want to hook function which does only 
the int 3 call? But nothing is impossible. You can think about it and you can 
find how to solve this. As I was thinking about this you can hook the following
function after this one (it would be damaged by rewritng first 5 bytes of the
previous function). Function DbgBreakPoint is 2 bytes long, so we can set some
flags here and try to write conditional jump on the begining of the second 
function ... But this is not our problem now. 
	With the problem of saving original function relates then unhooking.
Unhooking is changing replaces bytes back to the original state. When rewriting
IAT you will have to return original address to the table if you want to do 
unhooking. When using the five byte patch you will have to copy first original 
instructions back. Both ways are realy simple and no need to write more about
this.


=====[ 3.2.4 Other process hooking ]============================================
    
	Now we will do something practical with hooking during running. Who 
want to deal with hooking own process? That is good only for learning basics 
but it is not much practical.
	I'll show you three methods of other process hooking. Two of them use
API CreateRemoteThread which is only in Windows with NT technology. The problem
of hooking is not so interesing for older windows version for me. After all
I will try to explain third method which I didn't practise, so it could be 
unfunctional.
	At first few about CreateRemoteThread. As the help says this function
creates new thread in any process and runs its code.

	HANDLE CreateRemoteThread(
		HANDLE hProcess,
		LPSECURITY_ATTRIBUTES lpThreadAttributes,
		DWORD dwStackSize,
		LPTHREAD_START_ROUTINE lpStartAddress,
		LPVOID lpParameter,
		DWORD dwCreationFlags,
		LPDWORD lpThreadId
	);

	The handle hProcess can be get by OpenProcess. Here we have to have 
necessary rights. The pointer lpStartAddress points on memory place in TARGET 
process where the first instruction for new thread is. Because new thread is 
created in target process it is in memory of target process. The pointer 
lpParameter points on argument which will be refered to the new thread.


=====[ 3.2.4.1 DLL Injection ]==================================================

	We are able to run new thread from any place in target process memory.
This is useless unless we have own code in it. The first method cheats on this.
It uses GetProcAddress to get actual address for LoadLibrary. Then routes 
lpStartAddress to the address of LoadLibrary. Function LoadLibary has only one
parameter like the function for new thread in target process.

	HINSTANCE LoadLibrary(
		LPCTSTR lpLibFileName
	);

	We will use this similarity and we will refer the name of our DLL 
library as lpParameter. After running new thread lpParameter will be on a place
of lpLibFileName. The most important thing here is behavior decribed above. 
After loading new module into target process memory the initialization part is 
executed. If we place specific functions which will hook functions we want to
we will win this stuff. After execution of initialization part, the thread will 
have nothing to do and close but our module is still in memory. This method is 
realy nice and easy to implement. This is called DLL Injection. But if you are 
like I am, you don't like must of having DLL library. But if one doesn't care 
about having this library it is the easiest and the fastest method (from the 
programmers sight).


=====[ 3.2.4.2 Independent code ]===============================================

	Going on the way of independent code is very difficult but also very 
impressive thing. Independent code is the code without any statical addresses.
Everything is relative in it towards some specific place in itself. This code 
is mostly done if we don't know the address where this code will be executed.
Sure, it is possible to get this address and then to relink our code so as it 
will behave on the new address without errors but this is even harder than 
coding independent code. Example of this kind of code can be the virus code.
The virus which infects executables in the way it adds itself somewhere into
this executable. In different executables will be the virus code on different
places depended e.g. on file structure on length.
	At first we have to insert our code into target process. Then function 
CreateRemoteThread will take care of running our code. So, at first we have to
get some information about target process and get handle with OpenProcess. 
Then VirtualAllocEx will alloc some space in remote process memory for our 
code. Finally we will use WriteProcessMemory to write our code on allocated 
memory and run it. In CreateRemoteThread lpStartAddress will refer to allocated
memory and lpParameter can be whatever we want. Because I realy don't like any 
unnecesarry files I use this method.
 

=====[ 3.2.4.3 Raw change ]=====================================================

	There is not CreateRemoteThread in older windows version (without NT).
So we can't use this for hooking. There are probably other and better methods 
how to hook than the method I will talk about now. In fact I don't know if this
will work in practice (one never know when use Windows) but theoretically is 
everything ok.
	We don't need to have our code in target process to hook its functions 
at all. We have function WriteProcessMemory (this should be in all Windows
version) and we have OpenProcess, too. Last thing we need is VirtualProtectEx
which can change access to memory pages in target process. I can't see any 
reason why not to hook target process functions directly from our process...


=====[ 4. Ending ]==============================================================

	This small document ends. I will greet any extension which will 
describe unmentionde methods of hook, I am sure there are a lot of them. I will
also greet any extensions in the parts which were not described so intimately.
You can also send me some source codes if they are fecund for the problem of 
hooking e.g. for parts where I was lazy to write the code. The goal of this 
document is to show deatails of every technics of hooking. I hope I've done 
the part of this.
	Special thanks to Z0MBiE for his work, so I haven't to code it myself
and spend ages by studying tables for getting instruction length.

===================================[ End ]======================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -