Copy Link
Add to Bookmark
Report

Xine - issue #4 - Phile 102

eZine's profile picture
Published in 
Xine
 · 7 months ago

 
/-----------------------------\
| Xine - issue #4 - Phile 102 |
\-----------------------------/


APIs.txt
-------------------------------------------------------
As you know, Virus have to open files, read/write, close it, search files,
allocate memory, etc... I hope I don't learn anything to ya by that!
As you know, all functions in the windows' world are imports, that are
made in the .EXE executing... Here, I also hope...
Then, if I have a virus that infect "X.exe", and he have to open a file,
does he have to import "CreateFile" ? If so, he have to import
"ReadFile", "WriteFile", "CloseHandle", "GetFileSize", .....
So, what a mess to add so much imports to an import section of any file!
So, the possibility is to only import "LoadLibraryA" and
"GetProcAddress".
But, that's still annoying to change the import section... let's try
something else.

Ya know that win32 progs don't have to call "ExitProcess" to terminate,
they also can make a simple "ret" ( "ExitProcess" is only there if you
have to do that in a procedure, so that you don't know where you are w/
your stack ), your prog is like a subroutine of windows ;)

If Explorer launch your prog, it's like that:

Explorer: Kernel32: Your prog:
| /"CreateProcess:" / |
| / | / |
| / | / |
call "CreateProcess" / call Prog / |
<----------ret

So, if a ret at the beggining of the prog launch you to the middle
of "CreateProcess", you have a pointer in a location in kernel32
kewl...
Kernel32.dll is, in fact, a DLL. So, like an EXE, there is a MZ header,
a PE header, etc. So, there is the kernel "base" in memory where you
have the "MZ" of kernel. So, at kernel base + 3ch, you have a "pointer",
so that "MZ" + word ptr ["MZ" + 3ch] = "PE"
( nb: either you believe me, either you look for any PE format file )
So, at "PE" + 34h you have a dword, specifying the "Prefered RVA base"
of the file, in other words, the position of the "MZ" ;)
So, if edx = Kernel base:

set ebx = [edx+3ch]
[edx+ebx+34h] == edx :)

So, you have a pointer in Kernel ( somewhere ) and a condition that is
true
ONLY if a pointer is the kernel base; so, if you want the kernel base,
you have to decrement the pointer until the condition is true...

likeThis:
mov edx,[esp]
dec edx
mov ebx,[edx+03ch]
cmp edx,[edx+ebx+34h]
jnz likeThis
;edx = Kernel base

Yup! Now, you have the kernel base ("MZ")... I hope so.

Now, we have to import:

1st - Get the import table

So, look in any PE descriptor: the Export table RVA is at address "PE"
+ 78h
Note: an RVA is a relative address. for example, in [edx+3ch], there is
the RVA to "PE": that's a pointer in the file...
Suppose edx contain Kernel "MZ", let get Export table address in ebx.

mov ebx,edx ;ebx=MZ PTR
add ebx,[ebx+3ch] ;ebx=PE PTR
mov ebx,[ebx+78h] ;ebx=Export tables RVA
add ebx,edx ;ebx=Export tables PTR

Now, look in a Export table description: at address 20h ( in Export
table )
is a RVA to a table of RVA to asciiz names, and at address 18h, a dword
number, specifying the number of names

Export table: Table:-RVA1 ------------> "Function1"
| / -RVA2 ------------> "Hello"
| / -RVA3 ------------> "IMAFunction"
18h: 3 /
20h: RVA -------/
|

Now, I let ya imagine a "Search function":

RVAPtr = RVA1
CompareString( RVAPtr, FunctionToImport )
IfEqual => Found!
RVAPtr++
IfNotLast => Next!

Yeah, we have a pointer to the RVA to that function name ( or, either,
the
number of that function: if it's the 1st, the 2nd, ... )
Now, let's take that number ( it's the 16th for example ) and take
that 16th
exported function entry point: RVA to table of RVA to functions entry
points
is at 1ch, and number of exported functions is at 14h...
So, let's take the RVA nø16 in that table ( which RVA is at 1ch ),
put that RVA to fct EP in edi, for example, add edi,edx : edi is an RVA,
edx is kernel base so, edi = ptr to function EP, and call edi ;)

I hope you followed me...

Because that's not finished!

My system work quite well for any DLL, but not for kernel ;)
So, I had to "guess" what the problem was ( it call a wrong function )
and I'm laughing of you, telling you the number of names is at 18h, and
the number of exported function is at 14h, because there are not
always the same ( and they are not in kernel )
So, What are that unnamed functions ( because there is more functions
than
names, I hope ya guessed ;) )?
That are functions that are only exported by their cardinal... hehe.
So, that functions are placed BEFORE the named functions! Imagine
you found that the function you wanna import is the 16th, and that there
is 20 names and 25 exported functions: the function you have to reach
is the
16+(25-20) = 21th function! ( did you follow? cuz now it's finished )

There is the sources:

GetKrnlExport proc
;No reloc
;In: edx = kernel base
; esi = db[] name, 0
;Out: eax = PTR -> RVA of fct
;Just do 'mov eax,[eax]' 'add eax,edx' 'call eax' to use the fct
mov ebx,edx ;ebx=MZ PTR
add ebx,[ebx+3ch] ;ebx=PE PTR
mov ebx,[ebx+78h] ;ebx=Export tables RVA
add ebx,edx ;ebx=Export tables PTR

mov edi,[ebx+20h] ;edi=Names table RVA
lea edi,[edi+edx-4] ;edi=Names table PTR - 4
; cuz + 4 after
push edi
push esi
ESLoop:
mov edi,[esp+4]
mov esi,[esp]
add edi,4 ;Next name
mov [esp+4],edi
mov edi,[edi]
add edi,edx ;RVA->Ptr
ESStrLoop:
lodsb
cmp al,[edi]
jnz ESLoop ;Not equal, then next
inc edi
or al,al
jz ESFound ;0=end of string
jmp ESStrLoop
ESFound:
pop esi
pop edi ;edi=PTR -> fct name
sub edi,[ebx+20h] ;edi=Fct# * 4 + Kernel
sub edi, edx ;edi=Fct# * 4

mov eax,[ebx+1ch] ;eax=RVA -> export table

mov ecx,[ebx+14h] ;ecx=Nbr exprtd fcts
sub ecx,[ebx+18h] ;ecx-=Nbr names
add eax,edx ;eax=PTR -> export table
lea eax,[eax+4*ecx] ;eax=PTR -> named fcts
add eax,edi ;eax=PTR -> RVA of
looked fct

ret
GetKrnlExport endp

GetKrnlBase proc
;No reloc
;In: edx = begin [esp]
;Out: edx = kernel base
push ebx
GetKrnlBaseLoop:
xor ebx,ebx
dec edx
mov bx,[edx+03ch]
test bx,0f800h ;Max 7ffh!
jnz GetKrnlBaseLoop
cmp edx,[edx+ebx+34h]
jnz GetKrnlBaseLoop
pop ebx
ret
GetKrnlBase endp

------------------
Notes:
1st - That tutorial was made by n0ph on the 26-02-98, for IKX, for
XINE4.
2nd - If you find another way to do better, or anything else, write me
at
n0ph@HotMail.Com...
3rd - Visit "members.xoom.com/n0ph" !
4th - That's all folks!



← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT