Recent

Author Topic: "pChar" and "array of char" zero element problem  (Read 10140 times)

anna

  • Sr. Member
  • ****
  • Posts: 426
"pChar" and "array of char" zero element problem
« on: November 07, 2011, 01:58:38 pm »
Hello. Let me show you a piece of code I worry about:

var
  Fout1          :file;
  path:            string;
  old_offset_C34,
  left_to_read        :dword;
  planned_to_read:word;
  buf    : array[1..65535] of char;
  Buffer: pChar;
   NumRead, NumWritten : word;   
    pBytesRead,
    pBytesWritten      : PDWORD;
begin

    {----------------------------------------}
    {write memory file to physical file}
    {----------------------------------------}
      system.Assign (Fout1,Utf8ToAnsi(path));
      Rewrite (Fout1,1);
      old_offset_C34:=StartPos_ReadProcessMemory;
      planned_to_read:=Sizeof(buf);
      left_to_read:=code_VirtualSize;
      while  left_to_read>=planned_to_read do begin
       pBytesRead:=nil;
       ReadProcessMemory(hProcess,
                         pDWORD(old_offset_C34),
                         Buffer,
                         planned_to_read,
                         pBytesRead^);
         BlockWrite (Fout1,Buf,NumRead,NumWritten);
         old_offset_C34:=old_offset_C34+pBytesRead^;
         left_to_read:=left_to_read-pBytesRead^;
      end;
      pBytesRead:=nil;
      ReadProcessMemory(hProcess,
                        pDWORD(old_offset_C34),
                        Buffer,
                        left_to_read,
                        pBytesRead^);
      BlockWrite (Fout1,Buf,NumRead,NumWritten);
      system.close(Fout1);
    {----------------------------------------}


So question is how to connect Buf and Buffer?
Such way as for-loop I think is not elegant (not fast):
Code: [Select]
for i:=1 to Sizeof(buf) do buf[i]:=Buffer[i-1];
« Last Edit: November 07, 2011, 02:19:37 pm by anna »
WinXP SP3 Pro Russian 32-bit (5.1.2600)

anna

  • Sr. Member
  • ****
  • Posts: 426
Re: "pChar" and "array of char" zero element problem
« Reply #1 on: November 07, 2011, 02:24:42 pm »
Maybe it's possible to make such trick as:
var
 buf    : array[0..65534] of char;
...
begin
...
      ReadProcessMemory(hProcess,
                        pDWORD(old_offset_C34),
                        @buf,
                        //or maybe
                        //pChar(buf)
                        left_to_read,
                        pBytesRead^);
...
 
WinXP SP3 Pro Russian 32-bit (5.1.2600)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12023
  • Debugger - SynEdit - and more
    • wiki
Re: "pChar" and "array of char" zero element problem
« Reply #2 on: November 07, 2011, 02:40:08 pm »
In your first example you use Buffer (pchar), without ever initializing it.

PChar does not have any memory of it's own. You must either first allocate it, or set it to some existing memory. (PChar is just a pointer)

buffer := @buf[1]; 

with ansistring, you have to test, that the string has content, but for your array it will always work.

After this line buf and buffer are the same (using the same memory)

But yes you may not need the pchar variable.
If all you want to do, is calling a procedure that takes a pchar as argument.

Your 2nd looks correct




anna

  • Sr. Member
  • ****
  • Posts: 426
Re: "pChar" and "array of char" zero element problem
« Reply #3 on: November 07, 2011, 03:39:04 pm »
In your first example you use Buffer (pchar), without ever initializing it.

PChar does not have any memory of it's own. You must either first allocate it, or set it to some existing memory. (PChar is just a pointer)

I'm using:
Code: [Select]
GetMem( Buffer         , 65535  );
FillChar(Buffer^   , 65535, 0);
....
// working
....
FreeMem( Buffer         ,65535   );

If all you want to do, is calling a procedure that takes a pchar as argument.
Well this argunent receives a data: clusters of virtual file each of 65535 bytes .

Your 2nd looks correct
If I use next code , i see error.
      ReadProcessMemory(hProcess,
                        pDWORD(old_offset_C34),
                        pChar(buf)
                        left_to_read,
                        pBytesRead^);
unit1.pas(527,26) Error: Illegal type conversion: "Array[1..65535] Of Char" to "PChar"

This code compiled fine but I don't know works or not :
       ReadProcessMemory(hProcess,
                         pDWORD(old_offset_C34),
                         @Buf,
                         planned_to_read,
                         pBytesRead^);

But I don't understand where is byte of offset 'old_offset_C34' (first read byte)? In buf[1] or buf[0] or somewhere else?

If buf is declared as 'array [1..65535] of char ', then where is first read byte?
And if buf is declared as 'array [0..65534] of char ', then where is first read byte?
« Last Edit: November 07, 2011, 04:12:02 pm by anna »
WinXP SP3 Pro Russian 32-bit (5.1.2600)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12023
  • Debugger - SynEdit - and more
    • wiki
Re: "pChar" and "array of char" zero element problem
« Reply #4 on: November 07, 2011, 04:28:50 pm »
The compiler allows you to typecast a string to pchar. (I haven't tested with shortstring)

var s: ansistring;
you can just do "pchar(s)".

This is a special case, for which the compiler has special support.

for all else pchar = ^char
so you need the address of a char.

Your array is not a string, so the compiler does not do any special conversion.

if you do
   buffer := @buf[1];
then "buffer[0]" and "buf[1]" are equla (they are the same byte in memory, changes to either one, reflect in the other)

if you do
   buffer := @buf[5];
then "buffer[0]" and "buf[5]" are equal



So actually it should be
Code: [Select]
ReadProcessMemory(hProcess,
                        pDWORD(old_offset_C34),
                        @buf[1],  // since 1 is the lowest index of buf / first char in buf
                        //or maybe


You can also make buffer a string (if you use $H+ or ansistring / rawbytestring in fpc 2.7.1)
and use setlength to allocate memory

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: "pChar" and "array of char" zero element problem
« Reply #5 on: November 07, 2011, 06:14:14 pm »
You can also use move(src_var, dest_var, size_in_bytes) function when you need to quickly copy memory from 1 place to another.
(Note: you can simply set the pointer to same but it won't move the actual data inside)

Quote
for i:=1 to Sizeof(buf) do buf[i ]:=Buffer[i-1];
This would become:
Code: [Select]
move(buf[1], buffer[0], sizeof(buf));
« Last Edit: November 07, 2011, 06:38:17 pm by User137 »

anna

  • Sr. Member
  • ****
  • Posts: 426
Re: "pChar" and "array of char" zero element problem
« Reply #6 on: November 07, 2011, 07:05:52 pm »
Your array is not a string, so the compiler does not do any special conversion.
Yes, I read memory from some running executable. It's completely binary data .
« Last Edit: November 07, 2011, 09:34:10 pm by anna »
WinXP SP3 Pro Russian 32-bit (5.1.2600)

TurboRascal

  • Hero Member
  • *****
  • Posts: 672
  • "Good sysadmin. Bad programmer."™
Re: "pChar" and "array of char" zero element problem
« Reply #7 on: November 09, 2011, 12:10:33 am »
IIRC, PChar should be a zero-terminated string. So an array of char should have a zero appended to the end (assigned to buf[65535] here)...

I don't know if it's relevant for this application with binary data, but the PChar pointer doesn't have any idea how long it is if it's not zero-terminated (contrary to an array var, its length is stored nowhere)
Regards, ArNy the Turbo Rascal
-
"The secret is to give them what they need, not what they want." - Scotty, STTNG:Relics

 

TinyPortal © 2005-2018