2013-10-28 31 views
-1

我無法轉換,有人可以告訴我的方式嗎? :DC++到德爾福,memcpy和其他

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; 

tField在Delphi中,情況是工會(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; 

tField在C++中,我無法用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; 
}; 

程序和虛擬節點...

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); 
    } 
} 
+0

試試這個:'程序的getText(DST:PChar類型;外地:tField);',和使用'CopyMemory(dst,@ field.cstring,field.textLength);'。請記住,我不知道'TField'是如何聲明的。 – Jigsore

+0

訪問衝突 –

+1

您是否從其他'dst'中刪除了'@'? 'ReadProcessMemory(句柄,field.ptr,dst,field.textLength,NBR)''。 – Jigsore

回答

0

您在Delphi中定義的tField沒有與在C++代碼中定義的tField相同的內存佈局。

您確實需要檢查返回值ReadProcessMemory()以確保它實際上完全讀取數據,並且要注意最後一個參數的輸出值,以確保它按照您的要求讀取儘可能多的字節。

的原代碼德爾福的譯文看起來更像是這樣的:

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; 
+1

dst [field.textLength]:=#0;將更清潔 –

+0

我編輯的問題,我用這個過程,你通過並返回「地址004B34A6在模塊'Project1.exe'訪問衝突。地址004B3689」 –

+0

我寫的是避免使用指針算術, Delphi支持它。 –

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。我強烈懷疑它在移動中的使用不起作用。

+1

的#pragma包(1) 結構tField { \t工會名稱字段 \t { \t \t無效* PTR; \t \t char cstring [16]; \t} text; \t uint8_t textLength; \t char unknown1 [3]; \t uint8_t fieldType; \t char unknown2 [3]; \t uint32_t unknown3; }; –

+1

請不要在評論中提供詳細信息。請編輯問題。您還需要提供Delphi代碼。 –