Reverse Engineering for Beginners

(avery) #1

CHAPTER 92. OPENMP CHAPTER 92. OPENMP


if (found)
return;

memset (buf, 0, sizeof(buf));
sprintf (buf, "hello, world!_%d", nonce);

sha512_init_ctx (&ctx);
sha512_process_bytes (buf, strlen(buf), &ctx);
sha512_finish_ctx (&ctx, &res);
if (res[0]==0 && res[1]==0 && res[2]==0)
{
printf ("found (thread %d): [%s]. seconds spent=%d\n", t, buf, time(NULL)-start⤦
Ç);
found=1;
};
#pragma omp atomic
checked++;

#pragma omp critical
if ((checked % 100000)==0)
printf ("checked=%d\n", checked);
};


int main()
{
int32_t i;
int threads=omp_get_max_threads();
printf ("threads=%d\n", threads);


__min=(int32_t*)malloc(threads*sizeof(int32_t));
__max=(int32_t*)malloc(threads*sizeof(int32_t));
for (i=0; i<threads; i++)
__min[i]=__max[i]=-1;

start=time(NULL);

#pragma omp parallel for
for (i=0; i<INT32_MAX; i++)
check_nonce (i);

for (i=0; i<threads; i++)
printf ("__min[%d]=0x%08x __max[%d]=0x%08x\n", i, __min[i], i, __max[i]);

free(min); free(max);
};


Thecheck_nonce()function just adds a number to the string, hashes it with the SHA512 algorithm and checks for 3 zero
bytes in the result.


A very important part of the code is:


#pragma omp parallel for
for (i=0; i<INT32_MAX; i++)
check_nonce (i);

Yes, that simple, without#pragma we just callcheck_nonce()for each number from 0 toINT32_MAX(0x7fffffff
or 2147483647). With#pragma, the compiler adds some special code which slices the loop interval into smaller ones, to
run them on allCPUcores available^2.


The example can be compiled^3 in MSVC 2012:


cl openmp_example.c sha512.obj /openmp /O1 /Zi /Faopenmp_example.asm


Or in GCC:


gcc -fopenmp 2.c sha512.c -S -masm=intel


(^2) N.B.: This is intentionally simplest possible example, but in practice, the usage of OpenMP can be harder and more complex
(^3) sha512.(c|h) and u64.h files can be taken from the OpenSSL library:http://go.yurichev.com/17324

Free download pdf