В настоящее время я работаю над «Практическим обратным инжинирингом», одна из задач которого заключается в том, чтобы попросить меня декомпилировать подпрограмму ядра «ObFastDereferenceObject».Большая часть сборки довольно проста для понимания, но я не могу обернуться вокруг использования этой инструкции 'cmpxchg'.
Я понимаю инструкцию cmpxchg в целом (cmp dest, rax; если равно mov dest,source, иначе mov rax, dest), но в этой функции я не вижу, как cmpxchg может дать сбой.
nt!ObFastDereferenceObject:
sub rsp, 28h
mov r9, rdx
prefetchw [rcx]
mov rax, qword ptr [rcx]
mov r8, rax
xor r8, rdx
cmp r8, 0Fh
jae nt!ObFastDereferenceObject+0x29
nt!ObFastDereferenceObject+0x19:
lea r8, [rax+1]
lock cmpxchg qword ptr [rcx], r8
jne nt!ObFastDereferenceObject+0x33
nt!ObFastDereferenceObject+0x24:
add rsp, 28h
ret
nt!ObFastDereferenceObject+0x29:
mov rcx, r9
call nt!ObfDereferenceObject
jmp nt!ObFastDereferenceObject+0x24
nt!ObFastDereferenceObject+0x33:
mov rdx, rax
xor rdx, r9
cmp rdx, 0Fh
jb nt!ObFastDereferenceObject+0x19
nt!ObFastDereferenceObject+0x3f:
jmp nt!ObFastDereferenceObject+0x29
Поскольку (в строке 4) rax получает копию структуры _EX_FAST_REF, на которую указывает rcx,и поскольку ни rax, ни rcx, ни объект, на который указывает изменение rcx, cmpxchg, сравнивающий rax и [rcx], всегда должен оцениваться как равный, насколько я понимаю.(Крайне маловероятно, учитывая, что функция имеет секцию, которая выполняется только в том случае, если этот cmpxchg оценивается как «не равно»)