Nakon nekog vremena opet sam se vratio na taj lajbrari. Trenutno se zajebavam sa bufferima na heapu. Uglavnom - cilj je otkriti velicinu alociranog chunka na heapu kada imamo pointer na chunk (*ptr). Ukoliko pointer pokazuje na sam pocetak chunka, lako je otkriti velicinu chunka jer se ta vrijednost nalazi na *ptr-16 (16 bajtova), no ukoliko pointer pokazuje "dalje" unutar alociranog chunka - dolazi do problemcica. U tom slucaju potrebno je otkriti header chunka. Probao sam to rijesiti tako da se *ptr smanjuje dok odredjene vrijednosti u memoriji ne izgledaju kao chunk header, no to nije bas najsretnije rjesenje.
Probao sam istu stvar napraviti i sa _heapwalk() tako da se traversaju svi alocirani blokovi, pa ako *ptr pokazuje unutar chunka x i sljedeceg chunka x+1, uzima se velicina chunka x koji sadrzi adresu na koju pokazuje *ptr. Ovaj nacin je iako sporiji mozda cak i bolji, no u nekim slucajevima ne radi (cini mi se da ne radi ukoliko je blok manji od ~500 byteova)...mozda to ima kakve veze sa "wildernes" chunkom.
Ima ko kakvu ideju? :)
Ovo sam za probu pisao jucer navecer (metodom pokusaja i promasaja), tako da neke stvari treba izbaciti, neke dodati i sl. Svejedno, mislim da ovo nije pravo rjesenje.
Code:
unsigned long get_heap_size (char *ptr)
{
unsigned long *dw;
unsigned long *heap;
unsigned long ha;
char *tmp;
char a[1000];
// ....a.k.a GetProcessHeap()
__asm mov eax, DWORD PTR fs:[0x18] // get TEB
__asm mov eax, DWORD PTR [eax+0x30] // get PEB
__asm mov eax, DWORD PTR [eax+0x18] // get heap start addr from PEB
__asm mov ha, eax
heap = (unsigned long*)ptr;
if (((unsigned long)heap > ha) && ((unsigned long)heap < ha+4000000)){
// 5000000 - just very LAME test
tmp = (char*)heap;
while ((int)tmp % 8 != 0) { // align to 8
tmp++;
}
heap = (unsigned long*)tmp;
do {
if (*(heap-2) < 65535) // max chunk seg num. ?
{
//printf ("seg: %d\n",*(heap-2));
if (*(heap-3) == 1) { // previous_in_use
dw = heap - 4; // 4 ulong
break;
}
}
} while ((unsigned long)heap-- > ha);
_snprintf (a,1000,"bla: %d\n", *dw);
OutputDebugString(a);
}
return 0;
}
Leon Juranic