c ++ - Interprocess Memory Editing - Finde ændrede adresser

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg gør i øjeblikket en af ​​de spillespilere som et lille projekt. Jeg har allerede kørt ind i et problem; Når du 'går ind på et andet niveau', ændres adresserne for ting som brændstof, kontanter, kugler, deres adresser. Dette ville også ske, hvis du skulle genstarte applikationen.


Hvordan kan jeg finde disse adresser igen?


Jeg har lyst til at det er et ret grundlæggende spørgsmål, men det er en af ​​de 'det er eller ikke er muligt' spørgsmål til mig. Skal jeg bare stoppe med at se og glemme konceptet helt? 'For hårdt?'

Bedste reference


Det er lidt svært at beskrive præcis, hvordan man gør dette, da det er stærkt afhængige af det program du studerer, og om forfatteren gik ud, hvis hans måde at gøre dit liv svært. Bemærk, at jeg kun har gjort det en gang, men det fungerede rimeligt godt, selvom jeg kun vidste en lille forsamling.


Hvad der sandsynligvis sker er, at værdierne er allokeret på bunken ved hjælp af et opkald til malloc/new og hver gang du skifter niveau, bliver de ryddet op og omfordelt et andet sted. Så ideen er at se på programmets samlingskode for at finde, hvor markøren, der returneres af malloc, er gemt, og finde ud af, hvordan man pålideligt kan læse indholdet af markøren og finde den værdi, du søger.


Første ting du vil have er en debugger som OllyDbg og et grundlæggende kendskab til samling. Start derefter med at indstille et læsnings- og skrivebrudpunkt på den variabel, du vil undersøge. Da du sagde, at du ikke kan fortælle præcis, hvor variablen er du nødt til at sætte processen i pause, mens den kører og søger programmets hukommelse for værdien. Forhåbentlig vil du ende med kun få resultater at sive igennem, men være mistænkelig for alt der står på stakken da det måske bare er en kopi til et funktionsopkald eller til lokal brug. [3]


Når brudpunktet er indstillet, skal du køre programmet indtil en pause opstår. Nu er alt hvad du skal gøre, kigget på koden og undersøge, hvordan variablen er tilgængelig. Hvis det bliver overført som parameter, skal du undersøge funktionens opkaldssted. Hvis det bliver åbnet via en peger, skal du notere det og begynde at undersøge pegeren. Hvis det bliver åbnet som en forskydning af en peger, betyder det at den er en del af en datastruktur, så noter det og begynder at undersøge den anden variabel. Og så videre.


Hold fokus på din variabel og fortsæt med at undersøge koden, indtil du til sidst finder rod, som kan være en af ​​to ting:



  • En global variabel, der har en statisk adresse. Dette er det nemmeste scenario, da du har en statisk adresse, der er hardcoded lige ind i den kode, du kan bruge til pålideligt at gå gennem datastrukturerne.

  • En stabel tildelt variabel. Dette er vanskeligere, og jeg er ikke helt sikker på, hvordan man håndterer dette scenario pålideligt. Det er muligt, at dens adresse vil have samme forskydning fra starten af ​​stakken det meste af tiden, men det kan ikke. Du kan også gå i stakken for at finde den tilsvarende funktion og dens parametre, men det er lidt vanskelig at få det rigtige.



Når du har en adresse, er alt, hvad du har brug for, til at bruge ReadProcessMemory til at finde din variabel ved hjælp af de oplysninger, du fandt. For eksempel, hvis den adresse du har repræsenterer en peger til en datastruktur, hvor der ved opstilling 0x40 er brændstofværdi gemt, så skal du læse værdien på adressen, tilføje 0x40 til den og gøre en anden læses på resultatet. [4]


Bemærk, at adressen kun er gyldig, så længe den eksekverbare ikke ændres på nogen måde. Hvis den er kompileret eller patched, skal du starte igen. Jeg tror, ​​at du også skal være forsigtig med Windows 'ASLR, som kan ændre adressen rundt hver gang du starter programmet. [5]





Kommentar box var for lille til at passe til dette, så jeg vil lægge det her.


Hvis det er s esp plus en konstant så tror jeg på, at dette er en parameter og ikke en lokal variabel (bekræft ved at kontrollere layoutet af opkaldskonventionen). Hvis det er tilfældet, skal du træde program, indtil det vender tilbage til opkalderen, find ud af, hvordan parameteren er indstillet (se efter push instruktioner før opkalds instruktionen) og fortsæt med at udforske derfra. Da jeg gjorde dette, måtte jeg slappe af stakken en eller to gange, før jeg fandt den globale peger på datastrukturen.


Også esi -registret er ikke relateret til stakken (jeg var nødt til at se det op), så jeg 'tjekker, hvordan det bliver sat. Det kan være, at det indeholder datastrukturens adresse, og konstanten er forskydningen til variablen. Hvis du regner med, hvordan registret er indstillet, vil du være så meget tættere på markøren. [6]