Spørsmål:
Hvordan får jeg tilgang til en intern DLL-funksjon eller et stykke data eksternt?
theTheodidact
2018-07-04 01:46:52 UTC
view on stackexchange narkive permalink

Jeg skriver i C ++ og gjør en øvelse for å gjøre meg kjent med DLLer og delte objekter (.so). Hvordan får jeg tilgang til internt uten å eksportere dem? GetProcAddress returnerer null ved et anrop fra en ikke-eksportert funksjon. Jeg skrev DLL slik at jeg kjenner alle funksjons- og variabelnavn.

To svar:
josh
2018-07-04 05:51:27 UTC
view on stackexchange narkive permalink

Hvis du vet adressen til funksjonen din i DLL, kan du ringe på "C" -språk via en funksjonspeker. La oss lage et eksempel:

Anta at du har en funksjon som er bosatt i en DLL kalt "notExportedFunc" med signaturen

  int notExportedFunc (int a, int b);  

Du kan kalle det som i følgende hovedprogram:

  typedef int notExportedFunc (int a, int b); int main () {HANDLE h = LoadLibrary (L "mydll.dll"); // Bildebaseadresse, kan endres ved hvert anrop hvis (h == 0) {printf ("Kan ikke laste mydll.dll \ n"); retur -1; } int funcOffset = 0x11560; // fra linkerkartet int funcAddress = (int) h + funcOffset; notExportedFunc * f = (notExportedFunc *) (funcAddress); int resultat = f (3, 4); printf ("Resultat =% d \ n", resultat);}  

I koblingskartet ser de aktuelle oppføringene slik ut:

0000: 00000000 ___ImageBase 10000000 < === Linker Forslag

0001: 00000000 __enc $ textbss $ begin 10001000 Ikke relevant her

0001: 00010000 __enc $ textbss $ end 10011000 Ikke relevant her

0002: 00000560? notExportedFunc @@ YAHHH @ Z 10011560 f dllmain.obj

ImageBase-adressen returneres av "LoadLibrary (" mydll.dll ")" -anropet. Du bør være oppmerksom på at denne adressen vanligvis endres ved hver samtale til LoadLibrary, på grunn av ASLR (Address Space Layout Randomization). Derfor må adressen til notExportedFunc ikke hentes direkte fra linkerkartet, men må beregnes. I vårt eksempel er forskyvningen 0x11560, som må legges til adressen som returneres av LoadLibrary.

Resten av programmet er vanlig "C" -funksjonsanrop via en funksjonspeker.

Det kan være mulig å automatisere dette videre, men eksemplet viser forhåpentligvis den generelle mekanikken for å ringe private funksjoner i en DLL.

NirIzr
2018-07-04 14:25:27 UTC
view on stackexchange narkive permalink

GetProcAddr Windows API brukes til å hente adresser for eksporterte funksjoner. Den vil alltid returnere null for ikke-eksporterte funksjoner, da den ikke finner den i PE-filen.

Eksport av en funksjon er det som gjør den tilgjengelig for andre kjørbare filer. Uten å eksportere data om hvor i den kjørbare en funksjon ligger, er ikke tilgjengelig (dette er ikke helt sant, da symboler fremdeles kan avsløre den informasjonen, men de brukes ikke av GetProcAddr

Hvis du fremdeles ønsker å finne en funksjonspeker til en ikke-eksportert funksjon, må du følge en eksportert referansekjede. Hvis for eksempel func1 bruker func2 og func1 er eksportert, kan du få adressen til func1 og demonter deretter func1 til du finner anropet til func2 i den. Å kjenne igjen riktig samtale kan være litt vanskelig, men det er absolutt mulig.

This is a better option in cases where the DLL might change/update. Also I have seen this in exploits to call internal functions in DLLs. Although this will be harder to implement OP but it'll almost never break(assuming call chain for the function is same).


Denne spørsmålet ble automatisk oversatt fra engelsk.Det opprinnelige innholdet er tilgjengelig på stackexchange, som vi takker for cc by-sa 4.0-lisensen den distribueres under.
Loading...