1

I am reversing some malware and I came across this in my disassembly:

│           0x0040f5ec      8bd8           mov ebx, eax
│           0x0040f5ee      85db           test ebx, ebx
│       ┌─< 0x0040f5f0      7507           jne 0x40f5f9
│       │   0x0040f5f2      8bc6           mov eax, esi
│      ┌──< 0x0040f5f4      e9b3000000     jmp 0x40f6ac
│      │└─> 0x0040f5f9      57             push edi

As I understand it, testing a register with itself will always set the zero flag. JNE will then check the zero flag and jump if it's not set. If this is the case, why do we have the JNE jump right after testing a register against itself? Under what circumstances would it be executed?

Am I misunderstanding the TEST or JNE ops, or is there something else that I'm missing?

Thanks for any help and sorry if this is a stupid question.

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
Yapoz
  • 198
  • 13
  • 2
    Possible duplicate of [TEST Instruction - how it works?](http://stackoverflow.com/questions/23851287/test-instruction-how-it-works) – Ross Ridge Mar 12 '17 at 03:58
  • Possible duplicate of [What's the easiest way to determine is the register value equal to zero or not?](http://stackoverflow.com/questions/41174867/whats-the-easiest-way-to-determine-is-the-register-value-equal-to-zero-or-not) – Ped7g Mar 12 '17 at 10:48

2 Answers2

2

test performs an and operation. so if ebx contained a 3, anded with 3 is 3 which is not zero. But if ebx contained a 0 then 0 anded with 0 is zero. jne is based on the zero flag which is according to intel docs affected by a test instruction.

EDIT.

Disassembly of section .text:

0000000000000000 <.text>:
   0:   85 db                   test   %ebx,%ebx
   2:   3b 1c 25 00 00 00 00    cmp    0x0,%ebx

it is two bytes of instruction to use test to compare for zero or not. So that is likely why you will see test reg,reg then a jump if equal or not vs a compare with zero.

old_timer
  • 69,149
  • 8
  • 89
  • 168
  • OK, so it's an optimized way of saying `if(!ebx) jmp ...`? – Yapoz Mar 12 '17 at 03:35
  • 1
    Not dumb at all! It might have been asked at stackoverflow before though, but it is not obvious to everyone, and then even if the anding is understood then folks want to know why using the test instead of a compare with zero. xor ebx,ebx vs mov ebx,0 falls into this category as well. – old_timer Mar 12 '17 at 03:45
0

Some comments to make it a bit easier:

       0x0040f5ec      8bd8           mov ebx, eax    ;  
       0x0040f5ee      85db           test ebx, ebx   ;  if ( eax == 0 )
   ┌─< 0x0040f5f0      7507           jne 0x40f5f9    ;  {
   │   0x0040f5f2      8bc6           mov eax, esi    ;      eax = esi;
  ┌──< 0x0040f5f4      e9b3000000     jmp 0x40f6ac    ;  } else {
  │└─> 0x0040f5f9      57             push edi        ;      // call some method

https://en.wikipedia.org/wiki/TEST_(x86_instruction)

Slai
  • 22,144
  • 5
  • 45
  • 53