Каков размер size () в машинном коде? - PullRequest
0 голосов
/ 13 сентября 2018

В настоящее время я занимаюсь реверс-инжинирингом игры, и я столкнулся с проблемой, когда мне нужно вызвать GetRawInputData, которая ожидает pcbSize в качестве одного из аргументов.

Обычно в CI простонапишите sizeof(pData) но я понятия не имею, как это сделать в машинном коде.

Ответы [ 3 ]

0 голосов
/ 13 сентября 2018

Нет никакого эквивалента.sizeof - это конструкция времени компиляции, которая переводится как просто число в сборке.Т.е. sizeof (pcbSize) будет примерно 48 или 1024 или около того.Вы должны вычислить размер вручную или найти его в разобранном коде, если он вам нужен.

0 голосов
/ 13 сентября 2018

В сборке источника вы можете заставить ассемблер вычислять константы времени сборки как

msg: db "hello world", 10            ; 10 = ASCII newline
msglen equ $-msg

Затем, когда вы пишете mov edx, msglen, он собирается в mov edx, imm32 с подставленной константой. См. Как работает $ в NASM, в точности? для некоторых примеров.

Но в конечном машинном коде все константы времени сборки стали непосредственными или константами данных. (например, ptr_and_length: dq msg, msglen в разделе данных или родных данных объединяется в адрес и целое число qword, которое является только там в объектном файле, не рассчитанном во время выполнения из чего-либо.)


(Константы времени сборки могут также использоваться как счетчики повторений в макросах или других директивах. (Например,
times power imul eax, ecx собирается в блок из множества imul инструкций. power - целочисленная константа, определенная с помощью EQU. Или NASM %rep n / ... / %endrep)

Или используется в выражениях времени сборки, поэтому сам размер в буквальном смысле отсутствует в объектном файле, а является лишь результатом некоторых вычислений на его основе. (например, mov edx, msglen+2 или mov ecx, arrbytes/4, последний может быть в качестве границы для цикла, который учитывает слова, а не байты).

0 голосов
/ 13 сентября 2018

sizeof является чисто конструкцией системы типов C и полностью разрешается во время компиляции в простое число; в машинном коде такого нет, вероятно, вы просто найдете непосредственное значение в push или mov, соответствующее размеру pData.

Например, в нашей программе последовательность

RAWINPUT raw;
UINT dwSize = sizeof(raw);
GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &raw, &dwSize, sizeof(RAWINPUTHEADER));

переводится gcc 4.8 как

0x005f351d <+125>:   lea    eax,[ebp-0x48]                   // eax = &dwSize
0x005f3520 <+128>:   mov    DWORD PTR [esp+0xc],eax          // pcbSize = eax = &dwSize
0x005f3524 <+132>:   lea    eax,[ebp-0x38]                   // eax = &raw
0x005f3527 <+135>:   mov    DWORD PTR [ebp-0x48],0x28        // dwSize = sizeof(raw) i.e. 38
0x005f352e <+142>:   mov    DWORD PTR [esp+0x10],0x10        // cbSizeHeader = sizeof(RAWINPUTHEADER) i.e. 16
0x005f3536 <+150>:   mov    DWORD PTR [esp+0x8],eax          // pdata = eax = &raw
0x005f353a <+154>:   mov    DWORD PTR [esp+0x4],0x10000003   // uiCommand = RID_INPUT
0x005f3542 <+162>:   mov    DWORD PTR [esp],ecx              // hRawInput = lparam
0x005f3545 <+165>:   call   DWORD PTR ds:0x20967fc           // call GetRawInputData
...