Reverse Engineering for Beginners

(avery) #1

CHAPTER 92. OPENMP CHAPTER 92. OPENMP


92.1 MSVC


Now this is how MSVC 2012 generates the main loop:


Listing 92.1: MSVC 2012
push OFFSET _main$omp$1
push 0
push 1
call __vcomp_fork
add esp, 16 ; 00000010H

All functions prefixed byvcompare OpenMP-related and are stored in the vcomp*.dll file. So here a group of threads is
started.


Let’s take a look on_main$omp$1:


Listing 92.2: MSVC 2012

$T1 = -8 ; size = 4
$T2 = -4 ; size = 4
_main$omp$1 PROC ; COMDAT
push ebp
mov ebp, esp
push ecx
push ecx
push esi
lea eax, DWORD PTR $T2[ebp]
push eax
lea eax, DWORD PTR $T1[ebp]
push eax
push 1
push 1
push 2147483646 ; 7ffffffeH
push 0
call vcomp_for_static_simple_init
mov esi, DWORD PTR $T1[ebp]
add esp, 24 ; 00000018H
jmp SHORT $LN6@main$omp$1
$LL2@main$omp$1:
push esi
call _check_nonce
pop ecx
inc esi
$LN6@main$omp$1:
cmp esi, DWORD PTR $T2[ebp]
jle SHORT $LL2@main$omp$1
call
vcomp_for_static_end
pop esi
leave
ret 0
_main$omp$1 ENDP


This function is to be startedntimes in parallel, wherenis the number ofCPUcores.vcomp_for_static_simple_init()
calculates the interval for the for() construct for the current thread, depending on the current thread’s number. The loop’s
start and end values are stored in the$T1and$T2local variables. You may also notice7ffffffeh(or 2147483646) as an
argument to thevcomp_for_static_simple_init()function—this is the number of iterations for the whole loop, to
be divided evenly.


Then we see a new loop with a call to thecheck_nonce()function, which does all the work.


Let’s also add some code in the beginning of thecheck_nonce()function to gather statistics about the arguments with
which the function was called.


This is what we see when we run it:


threads=4
...
checked=2800000
checked=3000000
checked=3200000
checked=3300000

Free download pdf