-1

我无法转换,有人可以告诉我路吗?: D

void getText(char* dst, tField field)
{
    if(field.fieldType > 0xF)
    {
        ReadProcessMemory(handle,(LPCVOID) field.text.ptr,(LPVOID)dst, field.textLength, NULL);
    }
    else
    {
        memcpy((void*) dst, (void*)field.text.cstring, field.textLength);
    }   
    dst[field.textLength]=0;
}

我试过了,但不工作,很难。

procedure getText(dst: ShortString; field: tField);
var
  NBR: ULONG_PTR;
begin
  if field.fieldType > $F then
    ReadProcessMemory(tibiaProcess, field.text.ptr, @dst, field.textLength, NBR)
  else
    Move(field.text.cstring[0], dst, field.textLength);

  dst[field.textLength] := #0;
end;

Delphi 中的 tField,大小写为 union (C++)

type
  tField = record
    textLength: Int8;
    unknown1: String[2];
    fieldType: Int8;
    unknown2: String[2];
    unknown3: Integer;
    case Integer of
      0:
        (ptr: Pointer);
      1:
        (cstring: String[15]);
  end;

C++ 中的 tField,我在使用 CopyMemory 时遇到问题

#pragma pack(1)
struct tField
{
    union nameField
    {
        void* ptr;
        char cstring[16];
    } text;
    uint8_t textLength;
    char unknown1[3];
    uint8_t fieldType;
    char unknown2[3];
    uint32_t unknown3;
};

过程和vNode ...

vData = record
    a: Int32;
    b: Int8;
    c: Int8;
    unknown2: Int16;
    d: tField;
    e: tField;
    f: Int8;
  end;

  vNode = packed record
    previusNode, nextNode: Pointer;
    unk1: Int64;
    data: vData;
  end;

procedure printList();
var
  length, k: Integer;
  list: array of vNode;
  startingNodeAddress: DWORD;
  nextNodeAddress: Pointer;
  description, name: ShortString;

  NBR1, NBR2, NBR3, NBR4: Cardinal;
begin
  description := '';
  name := '';
  ReadProcessMemory(handle, ptr(LIST_LENGTH), @length, 4, NBR1);
  if (length > 0) then
  begin
    GetMem(Pointer(list), length * SizeOf(vNode));

    ReadProcessMemory(handle, ptr(LIST_BEGIN_PTR),
      @startingNodeAddress, 4, NBR2);
    ReadProcessMemory(handle, ptr(startingNodeAddress + 4),
      @nextNodeAddress, 4, NBR3);

    for k := 0 to length - 1 do
    begin
      ReadProcessMemory(handle, nextNodeAddress, @list[k], SizeOf
          (vNode), NBR4);
      nextNodeAddress := list[k].nextNode;
    end;

    for k := 0 to length - 1 do
    begin
      getText(name, list[k].data.d);
      ShowMessage(String(name));
    end;
  end;
end;

C ++,我的事情是一样的。

struct vNode
{
    void* previousNode;
    void* nextNode;
    uint64_t unknown1;
    struct vData
    {
        uint32_t a;
        uint8_t b;
        uint8_t c;
        uint16_t unknown2;
        tField d;
        tField e;
        uint8_t f;
    } data;
};
void printList()
{   
    uint32_t length;
    vNode* list;
    DWORD startingNodeAddress;
    void* nextNodeAddress;
    int k;
    char description[256];
    char name[256];


    ReadProcessMemory(handle, (LPCVOID)(LIST_LENGTH), (LPVOID)&length, 4, NULL);
    if(length>0)
    {
        list=(vNode*)malloc(length * sizeof(vNode));
        ReadProcessMemory(handle, (LPCVOID)(LIST_BEGIN_PTR), (LPVOID)&startingNodeAddress, 4, NULL);
        ReadProcessMemory(handle, (LPCVOID)(startingNodeAddress+4),&nextNodeAddress, 4, NULL);
        for(k=0;k<length;k++)
        {
            ReadProcessMemory(handle, nextNodeAddress,  (LPVOID)&list[k],  sizeof(vNode),  NULL);
            nextNodeAddress=list[k].nextNode;
        }


        for(k=0;k<length;k++)
        {
            getText(name,list[k].data.d);
            printf("%s", name);
        }
        free(list);
    }
}
4

2 回答 2

0

我会将其转换为返回 AnsiString 的函数。

procedure getText(field: tField): AnsiString;
var
  NBR: DWORD;
begin
  SetLength(Result, field.textLength);
  if (field.fieldType > $F) then
    ReadProcessMemory(handle, field.ptr, Pointer(Result), field.textLength, NBR)
  else
    Move(field.cstring, Pointer(Result)^, field.textLength);
end;

有一个附带条件。我们不知道 TField 是什么。所以我们不知道使用 TField 的成员是否合适。也许你翻译得不好。我不知道 cstring 是什么。我强烈怀疑它在 Move 中的使用是行不通的。

于 2013-10-28T18:42:55.303 回答
0

tField您在 Delphi 中定义的内存布局与C tField++ 代码中定义的内存布局不同。

您确实需要检查 的返回值ReadProcessMemory()以确保它实际上正在读取数据,并注意最后一个参数的输出值以确保它正在读取您请求的字节数。

将原始代码翻译成 Delphi 看起来更像这样:

type
  nameField = packed record
    case Integer of
      0: (ptr: Pointer);
      1: (cstring: array[0..15] of AnsiChar);
  end;

  tField = packed record
    text: nameField;
    textLength: Byte;
    unknown1: array[0..2] of AnsiChar;
    fieldType: Byte;
    unknown2: array[0..2] of AnsiChar;
    unknown3: LongWord;
  end;

  vData = record
    a: LongWord;
    b: Byte;
    c: Byte;
    unknown2: Word;
    d: textField;
    e: textField;
    f: Byte;
  end;

  vNode = record
    previousNode: Pointer;
    nextNode: Pointer;
    unknown1: UInt64;
    data: vData;
  end;
  PNodeList = ^vNodeList;
  vNodeList = array[0..MaxInt] of vNode;

procedure ReadProcMem(addr, dst: Pointer; numBytes: ULONG_PTR);
var
  numBytesRead: ULONG_PTR;
begin
  if not ReadProcessMemory(handle, addr, dst, numBytes, numBytesRead) then
    RaiseLastOSError;
  if numBytesRead <> numBytes then
    raise Exception.Create('Not all bytes were read!');
end;

procedure getText(dst: PAnsiChar; field: tField);
begin
  if field.fieldType > 0xF then
    ReadProcMem(field.text.ptr, dst, field.textLength)
  else
    Move(field.text.cstring[0], dst^, field.textLength);

  dst[field.textLength] := #0;
end;

procedure printList;
var
  length: LongWord;
  list: PNodeList;
  startingNodeAddress: DWORD;
  nextNodeAddress: Pointer;
  k: Integer;
  description: array[0..255] of AnsiChar;
  name: array[0..255] of AnsiChar;
begin
  ReadProcMem(Pointer(LIST_LENGTH), @length, 4);
  if length > 0 then
  begin
    GetMem(list, length * SizeOf(vNode));
    try
      ReadProcMem(Pointer(LIST_BEGIN_PTR), @startingNodeAddress, 4);
      ReadProcMem(Pointer(startingNodeAddress+4), @nextNodeAddress, 4);
      for k := 0 to length-1 do
      begin
        ReadProcMem(nextNodeAddress, @(list^[k]), SizeOf(vNode));
        nextNodeAddress := list^[k].nextNode;
      end;

      for k := 0 to length-1 do
      begin
        getText(name, list^[k].data.d);
        Writeln(name);
      end;
    finally
      FreeMem(list);
    end;
  end;
end;
于 2013-10-28T22:41:48.923 回答