0

I've seen this question which says __PAIR__ macro does some conditional computation. But I can not relate that with standard I/O handles. Here is the pseudocode in IDA:

if ( (char *)hConout - 1 <= (char *)0xFFFFFFFFFFFFFFFDi64 ) {
ConfigureStdHandles((PHANDLE)handle);
v175 = __PAIR__(1, (unsigned int)handle[0]);
v176 = __PAIR__(2, (unsigned int)handle[1]);
v177 = __PAIR__(2, (unsigned int)handle[2]);

Here is the corresponding Assembly:

loc_1400088CA:                          ; CODE XREF: wmain+FBF↑j
mov     [rsp+418h+handle+18h], rsi
lea     rax, [rsi-1]
cmp     rax, 0FFFFFFFFFFFFFFFDh
setbe   al
mov     rcx, [rsp+418h]
test    al, al
jz      loc_140008BAD
lea     rcx, [rsp+418h+handle] ; hIn
call    _ConfigureStdHandles
mov     esi, 1
mov     dword ptr [rsp+418h+var_268+4], esi
mov     eax, dword ptr [rsp+418h+handle]
mov     dword ptr [rsp+418h+var_268], eax
mov     dword ptr [rsp+418h+var_260+4], 2
mov     eax, dword ptr [rsp+418h+handle+8]
mov     dword ptr [rsp+418h+var_260], eax
mov     dword ptr [rsp+418h+var_258+4], 2
mov     eax, dword ptr [rsp+418h+handle+10h]
mov     dword ptr [rsp+418h+var_258], eax
cmp     [rsp+418h+var_230], r15b
jz      short loc_140008958
mov     [rsp+418h+var_268], r15
loc_140008958:  

The handles are for standard input, output and error respectively. Can you explain what does the __PAIR__ macro do with those handles?

  • show the corresponding asm – Igor Skochinsky May 25 '18 at 18:23
  • it appears like highpart(qword( x) = var; lowpart(qword(x) - another var; – blabb May 25 '18 at 19:36
  • nothing take a look at _LARGE_INTEGER structure and see the low part and high part and also as a qword – blabb May 25 '18 at 20:20
1

__PAIR__ represents a 64-bit value constructed from two 32-bit values. Because you have 64-bit variables (var_260 etc) being initialized by halves, decompiler detected a 64-bit move pattern and represented the right-hand side it as __PAIR__ helper. If you think it's wrong, you can fix it by:

  1. fixing the stack variable to be two 32-bit ones instead of one 64-bit. You can do it by opening the stack frame view (e.g double-click on the stkvar) and editing the frame structure (e.g with D key). After refreshing (F5), the decompiler should show simple 32-bit assignments without __PAIR__.

  2. splitting the 64-bit assignment into separate 32-bit ones. For that, use "Split Assignment" in the context menu.


EDIT I suspect that those stack variables are not 64-bit integers but actually small structs of two members, e.g.

struct handle_desc {
  int handle;
  int index;
}

maybe look at how they’re used later in the code.

  • After splitting v175 = __PAIR__(1, (unsigned int)handle[0]); becomes HIDWORD(v175) = 1; LODWORD(v175) = handle[0];. – Biswapriyo May 25 '18 at 19:54
  • yes, because the stkvar is still a 64-bit integer but high and low parts of it are being accessed separately. – Igor Skochinsky May 25 '18 at 20:03
  • How did you guess handle will be first member then index? – Biswapriyo Jun 11 '18 at 6:27
  • because handles are assigned to the low part of the variable. but you could try both and see which one works better. – Igor Skochinsky Jun 11 '18 at 6:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.