Weno no sabía muy bien donde poner esto pero supongo que ira aqui...
Lo que quiero es saber como puedo obtener la primera instruccion de una función de una DLL...
No pido asi un code que lo haga, sino más bien alguna caracteristica del formato PE que me diga donde empieza cada una de las funciones de una DLL...
Por ejemplo el EntryPoint nos dice la primera instruccion al ejecutarse (supongo que será la del Main), pues lo que quiero es saber como puedo obtener las posiciones de la primera instruccion de cada una de las funciones de una DLL...
Alguien sabe?
Saludos ;)
Es muy fácil..
Lo primero tienes que ir a la Export Table. Allí te indica todas las funciones que la dll exporta.
Para saber dónde comienza una determinada función de una librería, puedes implementarlo tú mismo con una forma muy sencilla y es llamando a la API GetProcAddress a la que le pasas el handle de la librería y el nombre (string) de la función que tú quieres. Esta pienso que es la forma más sencilla.
La forma teórica de dónde comienza cada función (resumo mucho mucho) es la siguiente:
En el encabezado (PE header) tienes una dirección hacia la Export Table. Por ej. voy a mirar una dll cualquiera y la miro con un editor de PE (o con un editor hexadecimal si sabes leer el PE header) y veo lo siguiente:
RVA Size
Export: 0002C0D0 00000092
En esta dll la Image Base es la siguiente: 04000000
Por lo tanto la Dirección Virtual donde comienza la Tabla de Exportaciones es:
0402C0D0
La export Table contiene las RVA (relativas a la base de la dll) de las funciones que exporta.
Ahora me voy a 0402C0D0 cargando la librería en el OllyDBG y dumpeo esa dirección y veo lo siguiente:
0402C0D0 00 00 00 00 0E 4A 76 41 00 00 00 00 16 C1 02 00 ....JvA....Á.
0402C0E0 01 00 00 00 03 00 00 00 03 00 00 00 F8 C0 02 00 .........øÀ.
0402C0F0 04 C1 02 00 10 C1 02 00 55 43 00 00 3B 42 00 00 Á.Á.UC..;B..
0402C100 DF 42 00 00 21 C1 02 00 31 C1 02 00 44 C1 02 00 ßB..!Á.1Á.DÁ.
0402C110 00 00 01 00 02 00 63 64 72 35 30 73 2E 64 6C 6C ....cdr50s.dll
0402C120 00 43 44 52 43 6F 6E 6E 65 63 74 44 72 69 76 65 .CDRConnectDrive
0402C130 00 43 44 52 47 65 74 53 75 70 70 6F 72 74 4C 65 .CDRGetSupportLe
0402C140 76 65 6C 00 43 44 52 47 65 74 53 75 70 70 6F 72 vel.CDRGetSuppor
0402C150 74 4C 65 76 65 6C 57 69 74 68 49 6E 71 75 69 72 tLevelWithInquir
0402C160 79 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 y...............
Como se observa el 4º dword es el puntero a la dll. Y a simple vista se ve que exporta únicamente 3 funciones.
Ahora después te paso un link con toda la información pero si te fijas en el offset 28h (40 decimal) verás estos bytes: 55 43 00 00 - 3B 42 00 00 - DF 42 00 00 Estos bytes son las RVA que tú buscas..
Por ejemplo para la primera función: CDRConnectDrive la RVA es 55 43 00 00 es decir, 4355h. Si recuerdas la Image Base es 4000000 por lo tanto la dirección virtual (recuerda: Dirección Virtual VA) es 4004355.
Voy a comprobarlo: cargo la librería en el OllyDBG y me voy a 4004355 y OllyDBG ya me indica dónde estoy y efectivamente me dice que estoy en CDRConnectDrive.
Así se calcula y así también lo hacen los editores de PE. Para más información y donde puedes compilar un programa en MASM32 te dejo el siguiente enlace:
http://win32assembly.online.fr/pe-tut7.html
Un saludo
karmany
Perfectamente explicado muchas gracias ya entiendo (así da gusto preguntar ;D ) :D
Voy a intentar hacer un code que me devuelva las direcciones, si tengo cualquier problema ya lo pongo...
Muchas gracias :D saludos ;)
Mira con el DUMPBIN ejecuté: dumpbin /EXPORTS zlib.dll ...aí se muestran las funciones que se exportan:
dumpbin /EXPORTS zlib.dll
Microsoft (R) COFF Binary File Dumper Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Dump of file zlib.dll
File Type: DLL
Section contains the following exports for zlib.dll
0 characteristics
39801DF8 time date stamp Thu Jul 27 13:33:12 2000
0.00 version
1 ordinal base
84 number of functions
61 number of names
ordinal hint RVA name
1 0 00001710 adler32
2 1 00001900 compress
39 2 00001850 compress2
3 3 000019A0 crc32
4 4 00001F70 deflate
5 5 000023A0 deflateCopy
6 6 000022F0 deflateEnd
7 7 00001B20 deflateInit2_
8 8 00001AF0 deflateInit_
9 9 00001EA0 deflateParams
10 A 00001E20 deflateReset
11 B 00001D20 deflateSetDictionary
38 C 00001920 get_crc_table
12 D 00003F50 gzclose
13 E 000034B0 gzdopen
34 F 00003EE0 gzeof
14 10 00003FE0 gzerror
15 11 00003BF0 gzflush
30 12 00003A10 gzgetc
41 13 00003A40 gzgets
16 14 00003230 gzopen
28 15 00003B30 gzprintf
29 16 00003B90 gzputc
40 17 00003BC0 gzputs
17 18 000037E0 gzread
32 19 00003E40 gzrewind
31 1A 00003CF0 gzseek
35 1B 000034F0 gzsetparams
33 1C 00003EC0 gztell
18 1D 00003AA0 gzwrite
19 1E 00005D30 inflate
20 1F 00005BA0 inflateEnd
21 20 00005BF0 inflateInit2_
22 21 00005D10 inflateInit_
23 22 00005B50 inflateReset
24 23 00006170 inflateSetDictionary
25 24 00006200 inflateSync
37 25 000062D0 inflateSyncPoint
26 26 00008700 uncompress
62 27 00008C60 unzClose
72 28 000098C0 unzCloseCurrentFile
64 29 00008CD0 unzGetCurrentFileInfo
73 2A 00009950 unzGetGlobalComment
63 2B 00008CA0 unzGetGlobalInfo
76 2C 00009810 unzGetLocalExtrafield
65 2D 000090B0 unzGoToFirstFile
66 2E 00009100 unzGoToNextFile
75 2F 00009180 unzLocateFile
61 30 00008860 unzOpen
67 31 00009270 unzOpenCurrentFile
68 32 000095B0 unzReadCurrentFile
74 33 000087A0 unzStringFileNameCompare
71 34 000097E0 unzeof
70 35 000097B0 unztell
36 36 0000A580 zError
84 37 0000A3A0 zipClose
83 38 0000A0E0 zipCloseFileInZip
80 39 000099E0 zipOpen
81 3A 00009AB0 zipOpenNewFileInZip
82 3B 00009FC0 zipWriteInFileInZip
27 3C 0000A570 zlibVersion
Summary
2000 .data
2000 .rdata
1000 .reloc
1000 .rsrc
A000 .text
A ver, si no me equivoco aqui 00001710 sreía la direccion (en Hex) de la funcion adler32, la direccion de la funcion compress sería 00001900. Me equivoco?
Entonces si voy a la direccion 00001900 (con un editor hexadecimal por ejemplo) me encontraré ante la primera instruccion que se ejecutará con la funcion compress...me equivoco?
EDIT: Si si que me equivoco pero no se en que...a lo mejor lo que obtení no son las direcciones de las funciones no se...miré con el olly y no me coincide...
Weno dejo más detalles de la cabecera de la libreria zlib.dll, a ver si me decis aí cual sería la primera instruccion de alguna de sus funciones (para exportar):
dumpbin /HEADERS zlib.dll
Microsoft (R) COFF Binary File Dumper Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Dump of file zlib.dll
PE signature found
File Type: DLL
FILE HEADER VALUES
14C machine (i386)
5 number of sections
39801DF8 time date stamp Thu Jul 27 13:33:12 2000
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
210E characteristics
Executable
Line numbers stripped
Symbols stripped
32 bit word machine
DLL
OPTIONAL HEADER VALUES
10B magic #
6.00 linker version
9A00 size of code
3800 size of initialized data
0 size of uninitialized data
A7B0 RVA of entry point
1000 base of code
B000 base of data
10000000 image base
1000 section alignment
200 file alignment
4.00 operating system version
1.12 image version
4.00 subsystem version
0 Win32 version
11000 size of image
1000 size of headers
0 checksum
2 subsystem (Windows GUI)
0 DLL characteristics
100000 size of stack reserve
1000 size of stack commit
100000 size of heap reserve
2000 size of heap commit
0 loader flags
10 number of directories
BFA0 [ 5D5] RVA [size] of Export Directory
BE18 [ 3C] RVA [size] of Import Directory
F000 [ 370] RVA [size] of Resource Directory
0 [ 0] RVA [size] of Exception Directory
0 [ 0] RVA [size] of Certificates Directory
10000 [ 264] RVA [size] of Base Relocation Directory
0 [ 0] RVA [size] of Debug Directory
0 [ 0] RVA [size] of Architecture Directory
0 [ 0] RVA [size] of Special Directory
0 [ 0] RVA [size] of Thread Storage Directory
0 [ 0] RVA [size] of Load Configuration Directory
0 [ 0] RVA [size] of Bound Import Directory
0 [ 0] RVA [size] of Import Address Table Directory
0 [ 0] RVA [size] of Delay Import Directory
0 [ 0] RVA [size] of Reserved Directory
0 [ 0] RVA [size] of Reserved Directory
SECTION HEADER #1
.text name
982A virtual size
1000 virtual address
9A00 size of raw data
400 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60000020 flags
Code
Execute Read
SECTION HEADER #2
.rdata name
1575 virtual size
B000 virtual address
1600 size of raw data
9E00 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
Read Only
SECTION HEADER #3
.data name
189C virtual size
D000 virtual address
1600 size of raw data
B400 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
Read Write
SECTION HEADER #4
.rsrc name
370 virtual size
F000 virtual address
400 size of raw data
CA00 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
Read Only
SECTION HEADER #5
.reloc name
2AE virtual size
10000 virtual address
400 size of raw data
CE00 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
42000040 flags
Initialized Data
Discardable
Read Only
Summary
2000 .data
2000 .rdata
1000 .reloc
1000 .rsrc
A000 .text
Saludos y gracias ;)
Al final ya lo conseguí :xD
La cuestion era: tengo el 00001900 (ese lo se obtener bien) de la funcion y le resto C00. El C00 es la diferencia entre las direcciones virtuales y las fisicas y lo obtengo restando 1000-400 (en HEX)...el 1000 es el virtual address de la primera sección y el 400 el file pointer to raw data de la primera sección. Y weno como cuando obtienes la direccion 00001900 te aparece sin la ImageBase no hace falta restarsela despues...
Weno saludos y gracias por todo ;)