Newsgroup: it.comp.programmare.win32
Titolo: [?] Recuperare Base Address di un processo

Ciao a tutti,
vorrei sapere come fare, in un sistema W9X, a recuperare l'indirizzo di
base di un processo, conoscendone il PID.
Per intenderci, è quello che [credo] potrebbe essere usato con
ReadProcessMemory() oppure Toolhelp32ReadProcessMemory()
mi servirebbe un link a documentazione e/o esempi in VB, ma va bene
anche se è in C o in Delphi (provo a tradurre :))
Grazie dell'attenzione
Faber
-------------------------
http://www.faberbox.com/
Home of Faber's Site
-------------------------

base di un processo, conoscendone il PID.
Il "base address" di un processo, sotto W9x e' un valore costante
(0x0040000).
--
CyberWalkie - walkietalkie(at)
libero.it

 (0x0040000).
uhmmm allora mi sa che non ho capito (probabile) o mi sono espresso male
(altrettanto probabile :))...
intendevo l'indirizzo di partenza dello spazio di memoria riservato ad
un processo in esecuzione (per questo parlavo di PID); tu ti riferivi al
Preferred Base?
Ciao e grazie
Faber

Preferred Base?
Da "Programmare Applicazioni per Microsoft Windows" di
Jeffrey Richter :
"PVOID GetModulePreferredBaseAddr( DWORD dwProcessId, 
                                   PVOID pvModuleRemote ) ;
 Questa funzione accetta l'ID di un processo e l'indirizzo
di un modulo in quel processo. QUindi, esamina lo spazio di
indirizzo del processo, individua il modulo e legge le
informzioni di intestazione del modulo per determinare
l'indirizzo base del modulo.  Un modulo dovrebbe sempre
essere caricato nell'indirizzo base."
Non so se puo' esserti d'aiuto.
--
CyberWalkie - walkietalkie(at)
libero.it

 (0x0040000).
Sei sicuro? Vuoi dire che l'opzione del linker (che generalmente ha quel
valore) viene ignorata?
In ogni caso credo che l'indirizzo di caricamento lo si possa trovare con
GetModuleHandle(NULL), chiamandolo nel processo remoto. Se non ricordo male
il "module handle" corrisponde effettivamente all'indirizzo di caricamento
del modulo, in questo caso al modulo principale.
---
Bye! Lorenzo Lutti
http://antani.virtualave.net/

(0x0040000).
   Era cosi` sotto win32s (e la s non era cosa da poco... :-)).
-- 
Totuccio.

   Era cosi` sotto win32s (e la s non era cosa da poco... :-)).
Che io sappia, e' ancora cosi'.
--
CyberWalkie - walkietalkie(at)
libero.it

Che io sappia, e' ancora cosi'.
   Chiedo perdono, ho detto una castroneria (andavo a memoria)
abnorme.
   Quello e` il valore predefinito, come dice mamma m$ (ma non l'unico
possibile, si cambia con un opzione del linker). Quindi siamo pari
:-)))) (scherzo!)
   Non so a cosa possa servire cambiarlo in win95/98/nt/2000/me/xp (ho
dimenticato niente? ;)), ma era invece OBBLIGATORIO (ecco la mia
castroneria: ho detto esattamente l'opposto) in win32s.
   Un eseguibile che volesse avere buone probabilita` di superare le
prime fasi di caricamento sotto win32s, avrebbe dovuto specificare
quasi necessariamente un indirizzo di base diverso da 0x400000,
perche` in quell'ambiente lo spazio di indirizzamento era unico.
   Nessuno toglie la possibilita` che qualcuna di quelle applicazioni
sia ancora in giro, o che un programmatore abbia preferito, per motivi
insondabili, dare un diverso indirizzo di base alla propria
applicazione. Quindi restano aperto, secondo me, il quesito di Faber.
-- 
Totuccio.

 
In realtà quello è il valore di default (come 0x10000000 è per le DLL) e 
può essere cambiato da un'opzione del linker.
GetModuleHandle(NULL) dovrebbe tornare il valore corretto.
-- 
Valter Minute
min...@inwind.it
 (the reply address of this message is invalid)

 GetModuleHandle(NULL) dovrebbe tornare il valore corretto.
ok, ma MSDN recita:
"The GetModuleHandle function returns a module handle for the specified
module if the file has been mapped into the address space of the calling
process."
mentre io ho bisogno di sapere il base address di un processo che non è
il mio, per questo parlavo di PID  :)
Faber

 
Per farlo dovresti richiamare GetModuleHandle da dentro il processo 
"target". 
Puoi farlo tramite un hook o utilizzando CreateRemoteThread (NT only).


 Puoi farlo tramite un hook o utilizzando CreateRemoteThread (NT only).
ci avevo pensato, ma mi sembra eccessivo fare un hook per sapere una
cosa cosě 'banale' (possibile che non si possa fare piů facilmente?!),
per quanto riguarda CreateRemoteThread nulla perché a me serve
recuperare il base address sotto sistemi 9X
Faber

 (0x0040000).
Quel valore č preso come esempio da molti compilatori/linker proprio per
seguire le regole della Win32 application ma nulla ti impedisce di
modificarlo dalle opzioni del linker (Su Delphi: Project > Options > Linker)
--
- Carlo -
c.b...@libero.it

 del modulo, in questo caso al modulo principale.
Ricordi bene.
Non è necessario richiamare GetModuleHandle() dal processo remoto, puoi
richiamare EnumProcessModules() passandole un solo Handle anzichè il
vettore.


Puoi farlo tramite un hook o utilizzando CreateRemoteThread (NT only).
buona fortuna ad iniettare un thread nel kernel
-- 
Posted from 
mx1.aruba.it
 [62.149.128.130] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

anche se è in C o in Delphi (provo a tradurre :))
vedi (documentazione libreria Tool Help):
 - funzione Module32First()
 - struttura MODULEENTRY32
non è detto che Module32First() ti dia per forza il modulo
"predefinito", cioè l'immagine eseguibile, anche se credo che sia vero
nella maggior parte dei casi :)
Casomai enumera i processi, quando trovi il pid che ti interessa ti
segni l'id del modulo di default, poi enumeri i moduli del processo e ti
fermi quando trovi quello con l'id corrispondente


 "target".
Ma scusa, mi pare sufficiente richiamare EnumProcessModules (se si lavora
sotto NT) oppure ottenerlo mediante le ToolHelp sotto 9x/2K.
EnumProcessModules dovrebbe restituire il modulo dell'exe se gli si passa un
solo hwnd anzichè un array.
Pseudo codice per Delphi:
Se la piattaforma consente l'utilizzo di ToolHelp:
  hSnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID);
  If hSnapShot<>-1 then
  begin
    IsNotLast:=Module32First(hSnapShot,ModuleEntry);
    While IsNotlast do
    begin
       if ModuleEntry.szModule = NomeMioExe then
             IsNotLast:= False {in questo caso ModuleEntry.modBaseAddr
dovrebbe contenere l'info richiesta}
           else
             IsNotLast:=Module32Next(hSnapShot,ModuleEntry);
    end;
  CloseHandle(hSnapShot);
Se la piattaforma NON consente l'utilizzo di ToolHelp:
hwnd hModule; [non un vettore]
hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
                                         false,ProcessID);
if hProcess <> 0 then
    EnumProcessModules( hProcess, @hModule, sizeof(hModule), cbReturned );
hModule contiene il base address del file "exe"
Ciao! :-)
--
- Carlo -
c.b...@libero.it
ps: spero di non aver scritto troppe vaccate visto che ho fatto uno pseudo
codice non testato

 
Perchè dovresti farlo? Si parlava di ricavare l'indirizzo di un altro 
processo, non del kernel. 
Comunque il kernel ha un base-address fisso, mi pare.


 fermi quando trovi quello con l'id corrispondente
sono proprio fuori dal mondo, avevo tutto sott'occhio ma guardavo alla
struttura PROCESSENTRY32 invece che MODULEENTRY32, per questo non
trovavo ciò che mi serviva  :)
effettivamente mi sembra la soluzione più saggia, se non fosse che ho
scoperto che in realtà non mi serve  :(
mi spiego: il mio scopo è riuscire a recuperare la riga di comando con
cui è stato lanciato un altro processo, quindi mi sono detto: "ma si,
smanetto un po' nella zona di memoria e lo trovo"... nada; ho fatto un
paio di prove ieri sera ma non ne sono uscito.
magari farò altre prove e vi farò sapere, cmq se qualcuno ha un
suggerimento per risolvere questo problema ve ne sarei grato  :)
Ciao
Faber

 paio di prove ieri sera ma non ne sono uscito.
Perchè la riga di comando di un processo è contenuta nello spazio di
indirizzamento del
kernel (kernel32.exe), sopra i 2Gb, nella zona condivisa.
Un processo chiama GetCommandLine per conoscere la propria riga di comando.
Se non vuoi utilizzare un hook, puoi andare a pescarla nella memoria del
kernel :)
Ti spedisco una funzioncella esempio in email.
Ciao! Davide DG.

modificarlo dalle opzioni del linker (Su Delphi: Project > Options > Linker)
piu' che come esmpio e' una necessita'.. 0x0040000 in win9x e' un
valore hardcoded assunto dal PE loader come preferred base address x
gli exe.. il fatto che sia hardcoded semplifica al loader (velocizza)
la fase di mapping e fixup.. ovviamente come le dll anche gli .exe
possono aver altre preferred base address a pena pero' della velocita'
di caricamento (il loader deve applicare i fixups x rilocare
l'immagine).. il fatto che sia stato scelto  0x0040000 e' ovviamente
legato al layout dell'address space in win9x.. f.e. NT 3.5x utilizza
come preferred 0x0010000 mentre da > Nt 4 M$ ha "sincronizzato" gli
address (benche' ofcoz l'address space inizi cmq al v.a. 0x0010000)..
come conseguenda di questo riallineamento alcuni tendono a distribuire
exe in cui la sect .reloc e' stripped dato che cmq l'exe verra mappato
sempre allo stesso base addr.
Saluti,
Walker Boh

hModule contiene il base address del file "exe"
concordo: credo che TH32 ed eventualmente PSAPI siano le soluzioni
migliori..
alternativamente x "omogenizzare" la portabilita' NT/2k si puo'
ricorrere alla omnipresente query api oppure, x i piu' smaliziati,
andarsi a leggere il base address (offset 0x08) dal PEB (process
enviroment block) che e' sempre (per ora, cioe' NT 4, 2k, XP) )
mappato al V.A. 0x7FFDF000.
Saluti,
Walker Boh

paio di prove ieri sera ma non ne sono uscito.
devi ricorre a soluzioni sostanzialmente semi-undoc.. 
win9x:
la command line e' memorizzate nel EDB (enviroment database ) .. il
ptr al TDEB lo trovi nel PDB (process database offset 0x40 in win95 ,
).. per avere un ptr il PDB bisogna utilizzare lo sporco trucco
illustrato da Pietrek ovvero calcolare il val dell'obfuscator e xorare
il PID del processo.. 	
invoke 	GetCurrentProcessId
mov	ebx, [esp-8h] stack
xor	eax, ebx
eax == obfuscator
win NT/2k puoi leggere la command line dalla struct PROCESS_PARAMETERS
(offset 0x40 IIRC)  puntata dal PEB (process eviroment block, offset
0x10 ) del processo;
quanto al PEB  e' sempre mappato al virtual address 0x7FFDF000 in ogni
processo (cioe' e' valido x NT/2k/XP.. cmq ottenibile usando
NtQueryInformationProcess.. almeno x ora =P)
inutile dire che si tratta di pratiche non proprio corrette.. cmq
sperimentare non e' un delitto..
Saluti,
 WalkerBoh

 eax == obfuscator
Ummm... [esp-8h] stack .... :)  Io faccio
asm
        CALL    GetCurrentProcessId // EAX  := pid
        XOR     EAX, FS :[$30]       // obsfucator  := pid xor (ptib^.ppdb)
end;
cosa cambia ?
approfitto del thread per chiederti na cosettaaa... :)   Il formato del
campo pdb^.ThreadList ...
è valido sotto 98 ? Sto provando ma senza successo :(
Ciao!! Davide DG.

 facilmente?!),
Potresti anche provare (ma non sono affatto certo che funzioni) con
GetWindowLong( hwnd, GWL_HINSTANCE) con una finestra del processo remoto.
Anche l'HINSTANCE aveva una corrispondenza diretta con l'indirizzo di
caricamento del modulo, ora non so piu`.


 caricamento del modulo, ora non so piu`.
ci sono processi che non hanno finestre  :)
Faber

sperimentare non e' un delitto..
non sai mica dove trovare piů documentazione? agratise s'intende... io
per ora mi arrangio con gli aggiornamenti online dei vari Undocumented /
Unauthorized, ma i libri completi costano una fortuna...


è valido sotto 98 ? Sto provando ma senza successo :(
yup.. pero' avendo presente appunto quel cambiamento di cui sopra..
cmq *ThreadList punta alla tail della lista circolare e *ThreadList+4
alla head.. ogni entry ha poi la struct base
Node *prev
Node *next
TDB  *pTDB
Saluti,
 Walker Boh

Unauthorized, ma i libri completi costano una fortuna...
oddio.. i books fondamentali li ho acquistati o fatti acquistare
(questo lavoro ha pure qualche risvolto positivo =P ) cmq ho anche
raccattato abbastanza doc in net (+ che altro srcs con utili headers a
corredo).. diciamo che sono un abuser di google =) .. il resto l'ho
ottenuto come te a suon di sessioni in IDA e windbg (che la sa lunga
sugli internals di NT/2k ;) 
cmq vedo di mandarti in mail qualke info al riguardo di
documentazione.."agratise s'intende" =P
Saluti,
 Walker Boh

 sperimentare non e' un delitto..
dici che non è corretto se implemento questa funzionalità per il mio
programma?
Ciao
Faber
P.S.: grazie davvero, a tutti, per i suggerimenti e le idee su come
risolvere il mio problema  :)

 programma?
Bah.. io ho iniziato ad interessarmi al'undocumented di windows quando ho
visto
cosa poteva fare questo programmino : 
http://atm.idic.caos.it
  ... ora
riesco a fare
quasi tutto quello che fa =)
Per il prob. assembler non so aiutarti, mi spiace, ma non ho mai programmato
in VB
(del basic conosco solo la sintassi ;P ).
Ciao! Davide DG

 TDB  *pTDB
Yupp!! Grazie :)
Ciao!! Davide DG.

documentazione.."agratise s'intende" =P
manda, manda, che qui non si butta via niente :P


 Windows :)
Meno costosi ma meno producenti! :-)
Ma quei famosi hacker che hanno attaccato M$ non hanno rubato i source di
Win? Azz ... :-)


Win? Azz ... :-)
ma come, non lo sai? la Microsoft li ha persi, i sorgenti <g>


 ma come, non lo sai? la Microsoft li ha persi, i sorgenti <g>
Speriamo che li abbia persi veramente, almeno XP non sarà il trito/ritrito
di NT e Win9x ...
Ciao!
