2015-04-15 12 views
5

* Başka kod güncelleştirme ve sorular * çalışmıyorbruteforce

sadece OpenCL yaklaşık 1 hafta ya da öylesine öğrenmeye başladı ve ben bruteforcing hakkında noktasına bir CUDA programını çalıştı ondan gerçek bir dize almak için bir MD5 hash. 2 dosya kullanıyorum: kernel.cl ve main.cpp.

//this is kernel.cl 

{...*defining some md5 variables*...} 

void IncrementBruteGPU(unsigned char* ourBrute, unsigned int charSetLen, unsigned int bruteLength, unsigned int incrementBy){ 
int i = 0; 
while(incrementBy > 0 && i < bruteLength) 
{ 
    int add = incrementBy + ourBrute[i]; 
    ourBrute[i] = add % charSetLen; 
    incrementBy = add/charSetLen; 
    i++; 
}} 

void md5_vfy(unsigned char* data, unsigned int length, unsigned int *a1, unsigned int *b1, unsigned int *c1, unsigned int *d1){ 
{...*some md5 hashing function*...}} 

__kernel void crack(unsigned int numThreads, unsigned int charSetLen, 
       unsigned int bruteLength, unsigned int v1, 
       unsigned int v2, unsigned int v3, unsigned int v4, 
       __constant unsigned char *cudaBrute, 
       __constant unsigned char *cudaCharSet, 
       __global unsigned char *correctPass){ 
//count index 
unsigned int idx = get_global_id(0); 
int totalLen = 0; 
int bruteStart = 0; 

unsigned char word[14]; 
unsigned char ourBrute[14]; 

int i = 0; 

for(i = 0; i < 14; i++) 
{ 
    ourBrute[i] = cudaBrute[i]; 
} 

i = 0; 
bruteStart = i; 
i+= bruteLength; 
totalLen = i; 

IncrementBruteGPU(ourBrute, charSetLen, bruteLength, idx); 
int timer = 0; 
for(timer = 0; timer < 200; timer++) 
{ 
    //substitute into string 
    for(i = 0; i < bruteLength; i++) 
    { 
     word[i+bruteStart] = cudaCharSet[ourBrute[i]]; 
    } 

    unsigned int c1 = 0, c2 = 0, c3 = 0, c4 = 0; 
    //find MD5 hash from word 
    md5_vfy(word,totalLen, &c1, &c2, &c3, &c4); 

    //compare hash with the input one 
    if(c1 == v1 && c2 == v2 && c3 == v3 && c4 == v4) 
    { 
     //place the right string into first index of array 
     int j; 
     for(j= 0; j < 14; j++) 
     { 
      correctPass[j] = word[j]; 
     } 
     correctPass[totalLen] = 0; 
    } 
    IncrementBruteGPU(ourBrute, charSetLen, bruteLength, numThreads); 
}} 

ve bu ana şudur: Bu program ile

//just the main, not the entire main.cpp 
int main(int argc, char** argv){ 
int digit=1; 
int charSetLen = 0; 
char hash[32]; 
char *strhash[32]; 

printf("Insert Hash: "); 
scanf("%s", strhash); 
system("cls"); 

int numThreads = BLOCKS * THREADS_PER_BLOCK; 

unsigned char currentBrute[14]; 
unsigned char cpuCorrectPass[14]; 

ZeroFill(currentBrute, 14); 
ZeroFill(cpuCorrectPass, 14); 

charSetLen = 65; 
unsigned char charSet[65]; 
memcpy(charSet, " [email protected]_", charSetLen); 
memcpy(hash, strhash, 32); 

//break hash into 4 processes of MD5 
unsigned int v1, v2, v3, v4; 
md5_to_ints(hash,&v1,&v2,&v3,&v4); 

//openCL starts here 
cl_platform_id cpPlatform;  // OpenCL platform 
cl_device_id device_id;   // device ID 
cl_context context;    // context 
cl_command_queue queue;   // command queue 
cl_program program;    // program 
cl_kernel kernel;     // kernel 

cl_int err; 
cl_mem correctPass; 
cl_mem cudaCharSet; 
cl_mem cudaBrute; 

size_t globalSize, localSize; 
size_t bytes = 14*sizeof(char); 

//5 work-groups 
localSize = 10; 
globalSize = 50; 

// Bind to platform 
err = clGetPlatformIDs(1, &cpPlatform, NULL); 
if(err < 0) { 
    perror("Couldn't identify a platform"); 
    exit(1); 
} 

// Get ID for the device 
err = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL); 
if(err == CL_DEVICE_NOT_FOUND) { 
    err = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_CPU, 1, &device_id, NULL); 
} 
if(err < 0) { 
    perror("Couldn't access any devices"); 
    exit(1); 
} 

// Create a context 
context = clCreateContext(0, 1, &device_id, NULL, NULL, &err); 
if(err < 0) { 
    perror("Couldn't create a context"); 
    exit(1); 
} 

// Create a command queue 
queue = clCreateCommandQueue(context, device_id, CL_QUEUE_PROFILING_ENABLE, &err); 
if(err < 0) { 
    perror("Couldn't create a command queue"); 
    exit(1); 
} 

// Build the program executable 
program = build_program(context, device_id, PROGRAM_FILE); 

// Create the compute kernel in the program we wish to run 
kernel = clCreateKernel(program, KERNEL_FUNC, &err); 
if(err < 0) { 
    perror("Couldn't create a kernel"); 
    exit(1); 
} 

// Create the input and output arrays in device memory for our calculation 
cudaBrute = clCreateBuffer(context, CL_MEM_READ_ONLY, 14, NULL, NULL); 
cudaCharSet = clCreateBuffer(context, CL_MEM_READ_ONLY, 95, NULL, NULL); 
correctPass = clCreateBuffer(context, CL_MEM_READ_WRITE, 14, NULL, NULL); 

// Write our data set into the input array in device memory 
err = clEnqueueWriteBuffer(queue, correctPass, CL_TRUE, 0, 
    bytes, cpuCorrectPass, 0, NULL, NULL); 
err = clEnqueueWriteBuffer(queue, cudaCharSet, CL_TRUE, 0, 
    bytes, charSet, 0, NULL, NULL); 

// Set the arguments to our compute kernel 
err = clSetKernelArg(kernel, 0, sizeof(unsigned int), &numThreads); 
err |= clSetKernelArg(kernel, 1, sizeof(unsigned int), &charSetLen); 
err |= clSetKernelArg(kernel, 2, sizeof(unsigned int), &digit); 
err |= clSetKernelArg(kernel, 3, sizeof(unsigned int), &v1); 
err |= clSetKernelArg(kernel, 4, sizeof(unsigned int), &v2); 
err |= clSetKernelArg(kernel, 5, sizeof(unsigned int), &v3); 
err |= clSetKernelArg(kernel, 6, sizeof(unsigned int), &v4); 
err |= clSetKernelArg(kernel, 7, sizeof(cl_mem), &cudaBrute); 
err |= clSetKernelArg(kernel, 8, sizeof(cl_mem), &cudaCharSet); 
err |= clSetKernelArg(kernel, 9, sizeof(cl_mem), &correctPass); 

bool finished = false; 
int ct = 0; 
while(true){ 
do{ 
    err = clEnqueueWriteBuffer(queue, cudaBrute, CL_TRUE, 0, 
     bytes, currentBrute, 0, NULL, NULL); 

// Execute the kernel over the entire range of the data set 
    err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &globalSize, &localSize, 
                  0, NULL, NULL); 

// Wait for the command queue to get serviced before reading back results 
    clFinish(queue); 

// Read the results from the device 
    clEnqueueReadBuffer(queue, correctPass, CL_TRUE, 0, bytes, cpuCorrectPass, 0, NULL, NULL); 

    if(cpuCorrectPass[0] != 0) 
    {  
     printf("MD5 Cracked---->\t"); 
     int k = 0; 
     while(cpuCorrectPass[k] != 0) 
     { 
      printf("%c", cpuCorrectPass[k]); 
      k++; 
     } 
     printf("\n\n"); 
     return 0; 
    } 
    finished = BruteIncrement(currentBrute, charSetLen, digit, numThreads * 200); 
    if(ct % OUTPUT_INTERVAL == 0) 
    { 
     printf("STATUS: "); 
     int k = 0; 
     for(k = 0; k < digit; k++) 
      printf("%c",charSet[currentBrute[k]]); 
     printf("\n"); 
    } 
    ct++; 
} while(!finished); 
    digit=digit+1; 
} 
// release OpenCL resources 
clReleaseMemObject(correctPass); 
clReleaseMemObject(cudaCharSet); 
clReleaseMemObject(cudaBrute); 
clReleaseProgram(program); 
clReleaseKernel(kernel); 
clReleaseCommandQueue(queue); 
clReleaseContext(context); 

return 0;} 

sorun asla doğru dize bulur olduğunu. Brute-hashes karşılaştıran fikri gibi görünüyor ve giriş hash çalışmıyor. CUDA sürümünün mükemmel çalıştığını gördüm.

lütfen bu doğru çalışmaz kılan söyle. Çekirdek ya hiç çalışmadığı ya da openCL okuma/yazma belleği & arabelleği hakkında anlayış eksikliği benim veya genel olarak neden bu yüzden. Eğer tüm dosyaları görmek istiyorsanız

*, bana isteyin. i çok uzun burada göndermeden eğer olacağını düşünüyorum çünkü. Teşekkürler ve kötü biçimlendirme için özür dilerim.

+0

sen (OpenCL API çağrıları dönüş kodları sorguluyor musunuz yani API sonra err' 'değeri aramak)? – jprice

+0

Bunu kontrol ettim, çekirdek oluşturmada bazı hata geri bildirimi aldım ve bunu düzeltdim. Şimdi problemler bu kernel.cl dosyasında. herhangi bir şansla, openCL özel başlık dosyasında bu değişkenleri doğru şekilde nasıl tanımlayacağınızı biliyor muydunuz? '__global __constant unsigned char cudaBrute [MAX_BRUTE_LENGTH]; __global __constant unsigned char cudaCharSet [95]; __global unsigned char correctPass [MAX_TOTAL]; ' – alfonsouchiha

+0

OpenCL arabelleklerinizi çekirdeğin (örneğin, global uchar * data) olarak bildirilen argümanlar olarak iletmeniz gerekir. – jprice

cevap

2

Çekirdeğiniz OpenCL çekirdek kaynak kodunuzda program kapsaminda tanimlanan sabit dizilerden okuyor ve yaziyor (cudaBrute, cudaCharSet, correctPass). Bu diziler başlatılamıyor ve ana bilgisayar hiçbir zaman çekirdeğin çıktılarını alamayacak. Giriş verisini ana bilgisayardan çekirdeğe aktarmak ve bir çekirdeğin sonuçlarını almak için, çekirdek değişkenlerini kullanmanız gerekir, çekirdek değişkenlerini programlamalısınız.

kernel'inizin tanımı aşağıdaki gibi görünmelidir:

__kernel void crack(unsigned int numThreads, unsigned int charSetLen, 
        unsigned int bruteLength, unsigned int v1, 
        unsigned int v2, unsigned int v3, unsigned int v4, 
        __global uchar *cudaBrute, 
        __global uchar *cudaCharSet, 
        __global uchar *correctPass) 
{ 
    ... 
    (do stuff with the arguments) 
    ... 
} 

ev sahibi kodundan argümanlar ayarlamak için, böyle bir şey yapacağını:

// Set the arguments to our compute kernel 
err = clSetKernelArg(kernel, 0, sizeof(int), &numThreads); 
err |= clSetKernelArg(kernel, 1, sizeof(int), &charSetLen); 
err |= clSetKernelArg(kernel, 2, sizeof(int), &digit); 
err |= clSetKernelArg(kernel, 3, sizeof(unsigned int), &v1); 
err |= clSetKernelArg(kernel, 4, sizeof(unsigned int), &v2); 
err |= clSetKernelArg(kernel, 5, sizeof(unsigned int), &v3); 
err |= clSetKernelArg(kernel, 6, sizeof(unsigned int), &v4); 
err |= clSetKernelArg(kernel, 7, sizeof(cl_mem), &cudaBrute); 
err |= clSetKernelArg(kernel, 8, sizeof(cl_mem), &cudaCharSet); 
err |= clSetKernelArg(kernel, 9, sizeof(cl_mem), &correctPass); 

Bildirimi ikinci argüman vardır serbest değişken çekirdek tanımında endeks ve nasıl son üç bağımsız değişkenler için şimdi biz clCreateBuffer ile oluşturulan tampon içerisinde geçmektedir.


(DÜZENLEME: Birkaç tane daha sorunlar daha da ayıklama sonra bulundu)

Sen ana bilgisayardaki digit değerini güncelliyoruz. Bu güncellenmiş değeri, her çekirdek çağrısının cihaza iletmek için, çekirdek argümanını yeniden ayarlamanız gerekir. Sadece sadece clEnqueueNDRangeKernel aramadan önce bu hattı geçerek bunu yapabilirsiniz: Eğer cudaCharSet tampon veri yazdığınızda

err |= clSetKernelArg(kernel, 2, sizeof(unsigned int), &digit); 

, size doğru miktarda yazıyoruz emin olmak gerekir. (65 olan) Kodunuz şu anda (14 olan) bytes kullanır, ama bu gerçekten charSetLen olmalıdır:

err = clEnqueueWriteBuffer(queue, cudaCharSet, CL_TRUE, 0, 
          charSetLen, charSet, 0, NULL, NULL); 
+0

Sonunda, bana geçen arabelleğe dair bir anlam ifade ediyor, teşekkürler. Ama yine de, bu 2 sorunu çözmez, nedenlerini bulamadı ... 'dim3 dimGrid (64); dim3 dimBlock (128); 'açıkCL içinde? – alfonsouchiha

+0

@alfonsouchiha Yerel boyut = '128', global boyut =' 128 * 64' – jprice

+0

'' her türlü değişkeni '' _global 'veya' _constant ', ör. _kernel void çatlak (_global int numThreads, _global int haneli, .....) {...} '? – alfonsouchiha