Thread: Stumped on old 16-bit code

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    93

    Stumped on old 16-bit code

    I've been trying to decipher this piece of old 16-bit Windows code and I just can't get it. The code was originally written in C and shown here interpreted by SoftIce; I guess a loose form of Assembly. The code fragment below is a loop; that I do know; which was confirmed in the IDA dissasembler. My comments are shown within "/* */". Any insight on how to transform this back to C would be greatly appreciated.

    Code:
    sub  ax ,ax        /* clear AX  AX=0000 */
    mov  [03DF], ax    /* put 0 in global variable int [03DF] */
    mov  [bp-14], ax    /* start loop  for (bp-14 = 0; bp-14 >= 8; bp-14++) */
    jmp  0752          /* takes the jump */
    0752: cmp  word ptr [bp-14], 08    /* bp-14 >= 8 part of "for" loop */
    jge  0784         /* no jump  jge tells me that [bp-14] is a "signed" int or "signed" word */
    mov  bx, [bp-14]    /* not a clue since [bp-14] is an int and "bx" register usually refers to pointers */
    shl  bx, 02        /* bx*4   EBX=0000 */
    add  bx, [03D0]    /* bx+[03D0]  global variable int [03D0] is equal to 0 */
    shl  bx, 1         /* bx*2 */
    push  ds           /* the up coming global variable [034E] is possibly a (char *)?? */
    push  word ptr [bx+034E]   /* finished product for operand 1 for lstrcmpi...DS:034E=0222 */
    lea  ax, [bp-12]           /* local variable char [bp-12]  operand 2 for lstrcmpi */
    push  ss
    push  ax
    call  lstrcmpi
    or  ax, ax       /* lstrcmpi statement must be conditional...maybe  if (lstrcmpi(operand 1, operand 2) == 0) */
    jnz  074F           /* no jump   BTW, AX=0000; EBX is still 0000 */
    mov  bx, [bp-14]    /* again clueless since [bp-14] is an int */
    shl  bx, 03         /* bx*8 */
    mov  ax, [bx+0354]   /* put [bx+0354] in AX...which BTW everything is equal to 0  */
    mov  [03DF] ax       /* put AX in [03DF]....which BTW means zeros for everyone */

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I would guess that bp-14 represents an array index, perhaps. strcmpi is "case-insensitive strcmp" so the two arguments there had better be pointers-to-char, not chars themselves. 03D0 had better contain the base address of the array then. strcmpi returns negative/0/positive just like strcmp, so your or ax,ax does exactly what you think it does.

  3. #3
    Registered User
    Join Date
    Jun 2009
    Posts
    93
    03D0 is a INT global variable which is the resultant of the statement:
    Code:
    03D0 = GetProfileInt(szIntl, "iDate", 0);
    I agree about lstrcmpi only working with strings, so somehow operand 1 needs to be (char) related. If [bp-14] and [03D0] are both INT's then that only leaves [034E] as a (char) I guess?..Somehow. So, I'm thinking something like: 034E[bp-14*4+03D0*2]. And then in the lstrcmpi call operand 1 "034E" is referenced as a (char * )???
    Last edited by TAZIN; 12-12-2010 at 12:02 PM.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    cmp word ptr [bp-14],
    This is telling me that bp-14 is an array index into an array of words. Perhaps SoftIce is mis-reading something and using an int as a char.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    I wrote 03D0, but that's because I somehow was looking back at the wrong line. The actual fetch uses 034E, not 03D0. So that's going to be your base address.

    And I would guess the bottom sets up the return value? And 0354+bx looks like it might be an array-addressing thing as well, since bx = 8*index value?

  6. #6
    Registered User
    Join Date
    Jun 2009
    Posts
    93
    I'm kinda sure that [bp-14] is a signed INT or WORD since it's refered to in other parts of the module as:
    Code:
    mov  word ptr [bp-14], 0
    inc  word ptr [bp-14]
    I guess the bottom part could be something like: 03DF = 0354[bp-14*8]....

  7. #7
    Registered User
    Join Date
    Jun 2009
    Posts
    93
    Ok, it looks like this loop is designed to compare two date pictures. One being the mess surrounding [034E], and the other stored in [bp-12]. The mess around [034E] gets one of its parameters from the function call GetProfileInt "iDate" which is set to default "0" meaning Month-Day-Year. Local char [bp-12] ends up being "M/d/yy" after a few statements prior to the code segment I posted. So, is there any way to re-construct this mess back to C given this information?

  8. #8
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    It seems to me to be something like:
    Code:
    int mem_03df = 0;
    char somebuffer[???]; /* Starts at [bp-12], length unknown */
    int i; /* [bp-14] */
    int bx;
    
    for(i = 0; i < 8; ) {
    	bx = mem_034e[i*4 + mem_03d0];
    	/*
    		Probably:
    		bx = mem_034e[i][mem_03d0];		
    	*/
    	if(lstrcmpi(somebuffer, bx) == 0)
    		break;
    }
    
    mem_03df = mem_0354[i*4];
    But it's extremely hard without being able to debug or know more about the values at runtime and where they come from.
    Last edited by EVOEx; 12-12-2010 at 05:32 PM.

  9. #9
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by EVOEx View Post
    It seems to me to be something like:
    Code:
    int mem_03df = 0;
    char somebuffer[???]; /* Starts at [bp-12], length unknown */
    int i; /* [bp-14] */
    int bx;
    
    for(i = 0; i < 8; ) {
    	bx = mem_034e[i*4 + mem_03d0];
    	/*
    		Probably:
    		bx = mem_034e[i][mem_03d0];		
    	*/
    	if(lstrcmpi(somebuffer, bx) == 0)
    		break;
    }
    
    mem_03df = mem_0354[i*4];
    But it's extremely hard without being able to debug or know more about the values at runtime and where they come from.
    Note by the way that mem_0354 overlaps with mem_034e. In fact, it's +6. So the code should be:

    Code:
    int mem_03df = 0;
    char somebuffer[???]; /* Starts at [bp-12], length unknown */
    int i; /* [bp-14] */
    int bx;
    
    for(i = 0; i < 8; ) {
    	bx = mem_034e[i*4 + mem_03d0];
    	/*
    		Probably:
    		bx = mem_034e[i][mem_03d0];		
    	*/
    	if(lstrcmpi(somebuffer, bx) == 0)
    		break;
    }
    
    mem_03df = mem_034e[i*4 + 3];
    /*
    Probably:
    mem_03df = mem_034e[i][3];
    */

  10. #10
    Registered User
    Join Date
    Jun 2009
    Posts
    93
    I think that if [0354] were a (char) or (char * ) then you'd end up with something like:
    Code:
    mov  bx, [bp-14]
    shl  bx, 03
    mov  al, [bx+0354]
    cbw
    mov  [03DF] ax
    The same would hold true I'd guess if [034E] were used since it's (char) based. I was under the impression that in 16-bit code (char) or (char * ) was 8-byte and therefore used the AL register, whereas and INT was 16-byte and used the AX register. That's why I choose an INT array for [0354].

  11. #11
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by TAZIN View Post
    I think that if [0354] were a (char) or (char * ) then you'd end up with something like:
    Code:
    mov  bx, [bp-14]
    shl  bx, 03
    mov  al, [bx+0354]
    cbw
    mov  [03DF] ax
    The same would hold true I'd guess if [034E] were used since it's (char) based. I was under the impression that in 16-bit code (char) or (char * ) was 8-byte and therefore used the AL register, whereas and INT was 16-byte and used the AX register. That's why I choose an INT array for [0354].
    034E (and 0354) is arrays of pointers to strings or, more likely, an array of array of strings. I think it looks like:
    Code:
    char something[8][2];
    Or so.

  12. #12
    Registered User
    Join Date
    Jun 2009
    Posts
    93
    Thanks EVOEx for the response. I too was thinking of something similiar after an array was suggested earlier.

    Code:
    int iTmp = 0;       /* [03DF] */
    char szBuffer[];    /* [bp-12] */
    int i;              /* [bp-14] */
    int iVal[];         /* [0354] */
    char szTemp[];      /* [034E] */
    
    for (i = 0; i < 8; i++)
    {
        if (lstrcmpi(szTemp[i*4 + iTmp*2], szBuffer) == 0)
            break;
    }
    
    iTmp = iVal[i*8];
    Now that I think about it, the way I show it a char array wouldn't work for operand 1 in the lstrcmpi function.....I think the compiler would through a error or warning.
    Last edited by TAZIN; 12-12-2010 at 08:00 PM.

  13. #13
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by TAZIN View Post
    Thanks EVOEx for the response. I too was thinking of something similiar after an array was suggested earlier.

    Code:
    int iTmp = 0;       /* [03DF] */
    char szBuffer[];    /* [bp-12] */
    int i;              /* [bp-14] */
    int iVal[];         /* [0354] */
    char szTemp[];      /* [034E] */
    
    for (i = 0; i < 8; i++)
    {
        if (lstrcmpi(szTemp[i*4 + iTmp*2], szBuffer) == 0)
            break;
    }
    
    iTmp = iVal[i*8];
    Now that I think about it, the way I show it a char array wouldn't work for operand 1 in the lstrcmpi function.....I think the compiler would through a error or warning.
    Well, you'll have to find out what the array it's compared with/read from is to understand what this function does. But your last line of code is wrong though: iVal is an array of 16 bits items (char pointer is my guess). So "i*8" should actually be "i*4".

  14. #14
    Registered User
    Join Date
    Jun 2009
    Posts
    93
    I kinda understand what your saying. Being somewhat new to C programming, an array of arrays is not the easiest concept to grasp. Thanks so much for the explanation.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Hamming code / even parity help
    By Striker9 in forum C++ Programming
    Replies: 1
    Last Post: 10-02-2009, 09:14 PM
  2. How does 0xff get represented on a 16 bit machine?
    By Overworked_PhD in forum C Programming
    Replies: 2
    Last Post: 10-27-2007, 11:32 AM
  3. 16 bit MS-Dos Subsystem Prob
    By darkmessiah in forum Windows Programming
    Replies: 2
    Last Post: 07-10-2005, 11:37 AM
  4. SSH Hacker Activity!! AAHHH!!
    By Kleid-0 in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 03-06-2005, 03:53 PM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM