libsplice
libsplice copied to clipboard
relative offset bug in x64
MessageBoxW:
00000000771F12B8 48 83 EC 38 sub rsp,38h
00000000771F12BC 45 33 DB xor r11d,r11d
00000000771F12BF 44 39 1D 76 0E 02 00 cmp dword ptr [__security_cookie_complement+34h (7721213Ch)],r11d
00000000771F12C6 74 2E je MessageBoxW+3Eh (771F12F6h)
3-я инструкция - cmp mem32, reg32 - состоит из 7 байтов. В ней первые три - это опкод команды, а последние 4 - адрес(displacement) в памяти переменной __security_cookie_complement. Причем этот адрес является относительным к текущему значению указателя инструкций (RIP, EIP). Такую команду при перемещении надо патчить - пересчитывать и изменять этот адрес. Этим и занимается код в ветке
/* if instruction has relative offset, calculate new offset */
if (ld.flags & F_RELATIVE) { ... }
Так вот, оригинальный код if ( _abs64((u64)(src + *((s32*)(old+1))) - (u64)old) > INT_MAX )
,
обращаясь к операнду displacement делает это по смещению 1 (old + 1). В то время, как смещение адреса в инструкции
выше - 3. Оригинальный код ошибочно считает часть опкода адресом и патчит его. Это естественно приводит к нежелательному результату.