I am working on reverse engineering an algorithm and I am using IDA. This is how the stack definition looks:

var_41E= word ptr -41Eh
s= byte ptr -412h
var_401= byte ptr -401h (v23)
var_400= byte ptr -400h (v22)- IDA shows as db 835
var_BD= word ptr -0BDh
var_13= byte ptr -13h (v25)
var_12= byte ptr -12h
var_11= byte ptr -11h
var_10= byte ptr -10h
var_F= byte ptr -0Fh
var_E= byte ptr -0Eh
var_D= byte ptr -0Dh
arg_0= dword ptr  8
dest= dword ptr  0Ch
arg_8= dword ptr  10h

There is this code block:

mov     al, [ebp+edx+var_12]
xor     [ebp+edx+var_400], al
inc     edx
cmp     edx, 4
jnz     short loc_1B41AA

Which translates to:

  v23[v11] ^= *(&v26 + v11);
while ( v11 != 4 );

The problem I'm having is, this v23 is never used. I was thinking perhaps this is a pointer to another spot in memory, but I'm unable to find this.

The next section of code reads:

  *(&v25 + v11) ^= *(&v22 + v11);
while ( v11 != 5 );

Which again, v22 is never used anywhere else. Nor is v25.

I feel like I'm missing something obvious. I have been able to reversed previous formula's so I just don't understand why this seems to allude me. I was thinking maybe this is some trash code to throw people off, but I'm not sure because I've replicated the rest of the process and the results aren't right. If I need to provide additional information, let me know.

Here is the entire code block for better reference: v9 is a 8 byte buffer. byte 0 is not used by the algorithm. I see "*(&v25 + v11) ^= *(&v22 + v11)" which seems like it could be altering this array? I suck at stack related things...

v26 = *(_BYTE *)(v9 + 1) ^ 0x42;
v27 = *(_BYTE *)(v9 + 2) ^ 0x4F;
v28 = *(_BYTE *)(v9 + 3) ^ 0x4C;
v29 = *(_BYTE *)(v9 + 4) ^ 0x37;
v30 = *(_BYTE *)(v9 + 5) ^ 0x37;
v10 = *(_BYTE *)(v9 + 6);
v11 = 0;
v31 = v10 ^ 0x36;
  v23[v11] ^= *(&v26 + v11);
while ( v11 != 4 );
LOBYTE(v11) = 1;
  *(&v25 + v11) ^= *(&v22 + v11);
while ( v11 != 5 );

.text:001B4166                 mov     esi, [ebp+arg_0]
.text:001B4169                 mov     edx, [esi+120h]
.text:001B416F                 add     esp, 10h
.text:001B4172                 mov     al, [edx+1]
.text:001B4175                 xor     eax, 42h
.text:001B4178                 mov     [ebp+var_12], al
.text:001B417B                 mov     al, [edx+2]
.text:001B417E                 xor     eax, 4Fh
.text:001B4181                 mov     [ebp+var_11], al
.text:001B4184                 mov     al, [edx+3]
.text:001B4187                 xor     eax, 4Ch
.text:001B418A                 mov     [ebp+var_10], al
.text:001B418D                 mov     al, [edx+4]
.text:001B4190                 xor     eax, 37h
.text:001B4193                 mov     [ebp+var_F], al
.text:001B4196                 mov     al, [edx+5]
.text:001B4199                 xor     eax, 37h
.text:001B419C                 mov     [ebp+var_E], al
.text:001B419F                 mov     al, [edx+6]
.text:001B41A2                 xor     edx, edx
.text:001B41A4                 xor     eax, 36h
.text:001B41A7                 mov     [ebp+var_D], al
.text:001B41AA loc_1B41AA:                             ; CODE XREF: USBIO::ReadDS1995KeyData(uchar *,ushort)+243j
.text:001B41AA                 mov     al, [ebp+edx+var_12]
.text:001B41AE                 xor     [ebp+edx+var_400], al
.text:001B41B5                 inc     edx
.text:001B41B6                 cmp     edx, 4
.text:001B41B9                 jnz     short loc_1B41AA
.text:001B41BB                 mov     dl, 1
.text:001B41BD loc_1B41BD:                             ; CODE XREF: USBIO::ReadDS1995KeyData(uchar *,ushort)+256j
.text:001B41BD                 mov     al, [ebp+edx+var_401]
.text:001B41C4                 xor     [ebp+edx+var_13], al
.text:001B41C8                 inc     edx
.text:001B41C9                 cmp     edx, 5
.text:001B41CC                 jnz     short loc_1B41BD
.text:001B41CE                 xor     ecx, ecx
.text:001B41D0 loc_1B41D0:                             ; CODE XREF: USBIO::ReadDS1995KeyData(uchar *,ushort)+283j
.text:001B41D0                 cmp     ecx, 11h
.text:001B41D3                 jbe     short loc_1B41DA
.text:001B41D5                 cmp     ecx, 15h
.text:001B41D8                 jbe     short loc_1B41F2
.text:001B41DA loc_1B41DA:                             ; CODE XREF: USBIO::ReadDS1995KeyData(uchar *,ushort)+25Dj
.text:001B41DA                 mov     edx, 6
.text:001B41DF                 mov     eax, ecx
.text:001B41E1                 mov     esi, edx
.text:001B41E3                 xor     edx, edx
.text:001B41E5                 div     esi
.text:001B41E7                 mov     al, [ebp+edx+var_12]
.text:001B41EB                 xor     [ebp+ecx+s], al
.text:001B41F2 loc_1B41F2:                             ; CODE XREF: USBIO::ReadDS1995KeyData(uchar *,ushort)+262j
.text:001B41F2                 inc     ecx
.text:001B41F3                 cmp     ecx, 400h
.text:001B41F9                 jnz     short loc_1B41D0
.text:001B41FB                 xor     esi, esi
.text:001B41FD                 lea     ecx, [ebp+s]
.text:001B4203                 xor     edx, edx
  • 2
    possibility of getting an answer may increase if you can edit in the actual assembly instructions
    – blabb
    Aug 3, 2017 at 10:01
  • @blabb full assembly added for the code segment.
    – Thomas
    Aug 3, 2017 at 13:36
  • @blabb I rewrote the issue in an attempt to clear up what I'm asking. I feel like you're answer is close but I'm missing something suttle.
    – Thomas
    Aug 4, 2017 at 2:33
  • I've rolled back the edit because the accepted answer did not match the question anymore. Please ask a new question instead, and include all relevant assembly for the pseudocode, including calls and pushes.
    – Igor Skochinsky
    Aug 4, 2017 at 9:31
  • @IgorSkochinsky Believe it or not, it was the same question as the answer was the same. The stack was not right. i needed to adjust the stack for v34 to be part of v33. It was like byte 8 in the array:).
    – Thomas
    Aug 4, 2017 at 13:31

1 Answer 1


that code is referencing a byte pointer inside a structure you need to define a structure in ida assign it members (it references 120 so your structure size should be > 120) and then define the bytepointer member and re analyze your program ida should now provide a better pseudo code

here is a small c code that could generate the code in assembly and its ida counter part posted as demo

src code as follows compiled and linked with vs 2015

#include <stdio.h>
#include <windows.h>
typedef struct _MYSTRUCT {
    DWORD memberone[72];
    PCHAR  membertwo;
}Mystruct , *PMystruct;
void docall(PMystruct argone) {
    char zo[8];
// disassembly refers to 2 byte in the string passed by addr @(edx+1)   
    zo[0] = argone->membertwo[1] ^ 13;
    zo[1] = argone->membertwo[2] ^ 37;
    zo[2] = argone->membertwo[3] ^ 94;
    zo[3] = argone->membertwo[4] ^ 94; 
    zo[4] = argone->membertwo[5] ^ 13;
    zo[5] = argone->membertwo[6] ^ 37;
    zo[6] = argone->membertwo[7] ^ 94;
    zo[7] = argone->membertwo[8] ^ 94;
        for(int i =0; i<8;i++)
            printf ("%c",zo[i]);
int main(void) {
    Mystruct teststruct;
    PCHAR mystr = "Oe@22e@22";
    teststruct.membertwo = mystr;
    return 0;

you can observe a striking similarity to the disassembly you edited in

.text:00401001 ; int __cdecl docall(Mystruct *argone)
.text:00401001 docall          proc near               ; CODE XREF: main+17p
.text:00401001 var_C           = byte ptr -0Ch
.text:00401001 var_4           = dword ptr -4
.text:00401001 argone          = dword ptr  8
.text:00401001                 push    ebp
.text:00401002                 mov     ebp, esp
.text:00401004                 sub     esp, 0Ch
.text:00401007                 mov     eax, __security_cookie
.text:0040100C                 xor     eax, ebp
.text:0040100E                 mov     [ebp+var_4], eax
.text:00401011                 mov     eax, [ebp+argone]
.text:00401014                 push    esi
.text:00401015                 mov     ecx, [eax+Mystruct.membertwo]
.text:0040101B                 mov     al, [ecx+1]
.text:0040101E                 xor     al, 0Dh
.text:00401020                 mov     [ebp+var_C], al
.text:00401023                 mov     al, [ecx+2]
.text:00401026                 xor     al, 25h
.text:00401028                 mov     [ebp+var_C+1], al
.text:0040102B                 mov     al, [ecx+3]
.text:0040102E                 xor     al, 5Eh
.text:00401030                 mov     [ebp+var_C+2], al
.text:00401033                 mov     al, [ecx+4]
.text:00401036                 xor     al, 5Eh
.text:00401038                 mov     [ebp+var_C+3], al
.text:0040103B                 mov     al, [ecx+5]
.text:0040103E                 xor     al, 0Dh
.text:00401040                 mov     [ebp+var_C+4], al
.text:00401043                 mov     al, [ecx+6]
.text:00401046                 xor     al, 25h
.text:00401048                 mov     [ebp+var_C+5], al
.text:0040104B                 mov     al, [ecx+7]
.text:0040104E                 xor     al, 5Eh
.text:00401050                 mov     [ebp+var_C+6], al
.text:00401053                 mov     al, [ecx+8]
.text:00401056                 xor     al, 5Eh
.text:00401058                 xor     esi, esi
.text:0040105A                 mov     [ebp+var_C+7], al
.text:0040105D loc_40105D:                             ; CODE XREF: docall+72j
.text:0040105D                 movzx   eax, [ebp+esi+var_C]
.text:00401062                 push    eax
.text:00401063                 push    offset asc_43B1A0 ; "%"
.text:00401068                 call    printf
.text:0040106D                 inc     esi
.text:0040106E                 pop     ecx
.text:0040106F                 pop     ecx
.text:00401070                 cmp     esi, 8
.text:00401073                 jl      short loc_40105D
.text:00401075                 mov     ecx, [ebp+var_4]
.text:00401078                 xor     ecx, ebp
.text:0040107A                 pop     esi
.text:0040107B                 call    __security_check_cookie
.text:00401080                 mov     esp, ebp
.text:00401082                 pop     ebp
.text:00401083                 retn
.text:00401083 docall          endp

find and convert the var a,b,c,x,y,.... to a proper sized array so that instead of var a, var b ida would show varx+1 , varx+2 etc

insert or define a structure of proper size

edit the function and set its function type (from a possible int to Mystruct *) using the above define struct

re analyze the program if you have hexrays redo the decompiling to see a fresh pseudo code should be much better than your present *x+*y+*z = *v/t-infinity

the code is xorring a specific portion(400 bytes) of the input with gaps in between (11h and 15h)

  • You were right, bad stack setup. Adjusted the variable sizes and it all lined up. I was able to get the new code working 100%. Thanks bro.
    – Thomas
    Aug 4, 2017 at 3:07
  • well i was going to write that var_12 is the first byte from xor @ 4178 edx = 0 ( there is a xor edx ,edx,) soi at 41aa it takes rhe first xorred byte and then xors 4 bytes cmp.....,5 then skips upto 11 , 15 with that jbe and xors the remaining 400. byte buffer. its good that you figured it out never trust odd pointers they are almost always array access if yiu defune an array all the odd ptrs will turn into an indexed accesd
    – blabb
    Aug 4, 2017 at 3:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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