I'm trying to load up an array with current system processes.
The result is page fault at first iteration.
First I allocate space for 100 PROCESSENTRY32 structures:
/* load processes in array */
mem.alloc ( @size(w.PROCESSENTRY32)*PROCLIST_INITSIZE);
mov (eax, pe32a_ptr);
LoadProcessList (hSnapshot, pe32a_ptr);
The LOADPROCESSLIST procedure is as follows:
//--------------------------------------------------------------------
// load a list of processes in an array of win32 PROCESSENTRY32
// structures
//--------------------------------------------------------------------
procedure LoadProcessList ( hSnap:DWORD; pe32a_ptr:DWORD); @nodisplay;
const
PE32SZ := @size(w.PROCESSENTRY32);
static
pe32:w.PROCESSENTRY32;
begin LoadProcessList;
push (eax);
push (ebx);
push (ecx);
push (edx); // count number of processes
push (esi);
push (edi);
mov (PE32SZ, pe32.dwSize);
w.Process32First (hSnap, &pe32);
cmp (eax, 0);
je NOP32FIRST;
/* Loop through all processes storing process info
in pe32a_ptr array */
xor (edx, edx);
cld ();
next_process:
intmul (PE32SZ, edx, ebx);
mov (pe32a_ptr[ebx], edi);
mov (&pe32, esi);
mov (PE32SZ, ecx);
rep.movsb();
inc (edx);
stdout.put (pe32a_ptr[ebx]);
w.Process32Next (hSnap, &pe32);
cmp (eax, 0);
je exitp;
jmp next_process;
NOP32FIRST:
stdout.put ("(!) No process information available.",nl);
exitp:
pop (edi);
pop (esi);
pop (edx);
pop (ecx);
pop (ebx);
pop (eax);
end LoadProcessList;
Any help? I'm using the rep.movsb properly?
thank you very much
mov (pe32a_ptr[ebx], edi); // edi = value at pe32a_ptr[ebx]
You want address of pe32a_ptr[ebx]
try:
lea ( edi, pe32a_ptr[ebx] ); // edi = address at pe32a_ptr[ebx]
Also, there is no guarantee that Windows will preserve EDX through API calls. You may want to preserve that.
ESI, EDI and EBX are pretty safe through API calls, but even then some buggy versions of Windows may fail to preserve those on rare occasions.
Once you work that out, you can significantly speed up the routine by using rep.movsd. Since we know @size (w.PROCESSENTRY32) >4 and dword-aligned, we can shift ecx to the right by 2 (effectively ecx = ecx/4) and use rep.movsd.
with LEA instruction gives me access violation.
Maybe I'm passing the pointer (p32a_ptr) from mem.alloc badly?
That's probably it. Seems like your procedure argument is by value.
Here's the way to get the proper address:
Use pass-by-reference in the procedure argument
procedure LoadProcessList ( hSnap:DWORD; var pe32a_ptr:DWORD); @nodisplay;
Then use a register to reference the address.
intmul (PE32SZ, edx, ebx);
mov (pe32a_ptr, edi); // edi = address of memory
add (ebx, edi); // edi = required offset
mov (&pe32, esi);
mov (PE32SZ, ecx);
...