#include #include #include #include #include "random.h" #define FLAG_LENGTH 64 /* visto che la prima cosa che si fa su un binario è usare strings una * frase per trollare va sempre bene */ const char *troll = "do you really think to found something using strings? :P"; /* nel fare le prove ho utilizzato questo codice kernel per vedere che la stringa calcolata fosse effettivamente quella giusta __kernel void polictf(__global char *array) { int gid = get_global_id(0); __local char flag[42]; flag[41] = 0; flag[gid] = gid^array[gid]; barrier(CLK_LOCAL_MEM_FENCE); if(gid == 0) printf(\"%s\\n\", flag); } */ /* questa è la stringa del codice deoffuscata __kernel void polictf(__global char *a){int i=get_global_id(0);__local char f[64];f[i]=i^a[i];} */ char obfuscated_code[] = { 0x48,0xdd,0x93,0x1c,0xb1,0x8a,0xe3,0x55,0x21,0xf8,0x0e,0x28,0xc5,0xb5, 0xcb,0x2d,0x54,0xf4,0x86,0xa7,0xd4,0xd1,0x72,0x52,0x78,0x5b,0x79,0x43, 0xd6,0x09,0x3d,0xd1,0x88,0xd4,0xda,0x3b,0xa4,0x8a,0xe2,0xed,0x45,0xca, 0x42,0x45,0x71,0x0d,0x93,0x4f,0xcf,0xbb,0xc6,0x0f,0x40,0x37,0xdf,0x5b, 0x86,0x32,0x5a,0x6a,0xfd,0x4d,0x3a,0x1b,0x36,0x3f,0x28,0x1d,0xe5,0xad, 0x75,0x2d,0x4c,0x5b,0x9f,0x30,0x12,0x5c,0x1f,0x76,0x52,0xe6,0xb3,0x3a, 0xe8,0xf3,0xe2,0xd6,0x40,0xf8,0x8d,0xd2,0x2a,0x1b,0xb0,0xa2 }; char *deobfuscated_code; int main(int argc, char *argv[]) { cl_platform_id platform; cl_device_id device; cl_context context; cl_command_queue queue; cl_program program; cl_kernel kernel; cl_mem mem; cl_event event; size_t work_size = FLAG_LENGTH; cl_int status_code = CL_SUCCESS; int i; /* const unsigned char flag[] = "debug_opencl_it_is_a_real_pain_in_the_ass"; for(i = 0; i < sizeof(flag); i++) obfuscated[i] = i^flag[i]; */ cl_char array[FLAG_LENGTH] = { 0x64,0x64,0x60,0x76,0x63,0x5a,0x69,0x77,0x6d,0x67,0x69,0x67, 0x53,0x64,0x7a,0x50,0x79,0x62,0x4d,0x72,0x4b,0x67,0x73,0x76, 0x74,0x46,0x6a,0x7a,0x75,0x73,0x41,0x76,0x4e,0x7e,0x56,0x4b, 0x41,0x7a,0x47,0x54,0x5b,0x29 }; /* prende la prima piattaforma OpenCL disponibile */ status_code = clGetPlatformIDs(1, &platform, NULL); /* seleziona il primo device della piattaforma selezionata * usando CL_DEVICE_TYPE_GPU forzo la ricerca di un device GPU, questo * vincolo può essere aggirato quando si debugga cambiando il valore in * CL_DEVICE_TYPE_ALL per poter usare i device CPU */ status_code = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL); /* nel caso in cui non si hanno device di tipo GPU un piccolo insulto */ if(status_code != CL_SUCCESS) { fprintf(stderr, "What???\nWhy don't you have an OpenCL capable GPU?\n"); return EXIT_FAILURE; } /* crea un contensto OpenCL e una relativa coda dei comandi */ context = clCreateContext(NULL, 1, &device, NULL, NULL, &status_code); queue = clCreateCommandQueue(context, device, 0, &status_code); mem = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, sizeof(array)*sizeof(cl_char), array, &status_code); /* deoffusca il codice OpenCL da eseguire. avendo questo codice è possibile * ricostruire il comportamento del programma per trovare la chiave. */ deobfuscated_code = malloc(sizeof(obfuscated_code)); for(i = 0; i < sizeof(obfuscated_code); i++) deobfuscated_code[i] = random_string[i+17]^obfuscated_code[i]; /* compila il programma appena deoffuscato e crea il relativo kernel */ program = clCreateProgramWithSource(context, 1, (const char **)&deobfuscated_code, NULL, &status_code); status_code = clBuildProgram(program, 1, &device, NULL, NULL, NULL); kernel = clCreateKernel(program, "polictf", &status_code); /* imposta l'argomento del kernel e lo lancia in esecuzione */ status_code = clSetKernelArg(kernel, 0, sizeof(mem), &mem); status_code = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &work_size, &work_size, 0, NULL, &event); /* aspetta la fine del programma kernel */ status_code = clWaitForEvents(1, &event); /* pulisce tutto */ clReleaseKernel(kernel); clReleaseCommandQueue(queue); clReleaseContext(context); clReleaseProgram(program); free(deobfuscated_code); return EXIT_SUCCESS; }