just thought i would post some stuff i'm working on.

the crcgen and getcrc procs are both size optimized, ill probably end up writing some speed optimized procs later,  the crccollision proc is pretty much brute force.

i had to multithread it because on my quad core, windows(xp) would only assign a single processor core per thread.

the code is pretty rough and needs some improvement however it does work pretty well.

anyways, all it does is appends a dword to the modified file, increments the dword then checks the crc against the original crc and loops till a collision happens.

edit: looks like im having issues with the multithreading. ill try to work that out tonight.
edit: race condition. anyways the code is UGLY ill clean it up later, but the error looks like its completely fixed.


.586
.model flat, stdcall
option casemap:none

include windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib

.data
filenameo db "orig.crc",0
filenamec db "coll.crc",0
error db "generic error message",0
format db "collision = %08lx",0
thread1 dword 0
thread2 dword 1
thread3 dword 2
thread4 dword 3
threads1 dword 000000000H
threads2 dword 03FFFFFFFH
threads3 dword 07FFFFFFFH
threads4 dword 0BFFFFFFFH
threads5 dword 0FFFFFFFFH

.data?
crctable dword 256 dup(?)
crc dword ?
hfileo dword ?
hfilec dword ?
fsizeo dword ?
fsizec dword ?
tempo dword ?
tempc dword ?
bytesread dword ?
collision dword ?
crcorig dword ?
falloc dword ?
threadid1 dword ?
threadid2 dword ?
threadid3 dword ?
threadid4 dword ?
tarray dword 4 dup(?)
output dword 10 dup(?)

.code

crccollision proc uses ebx ecx edx param:DWORD
mov ecx,
mov ebx, ecx
mov ebx,
mov ecx,
shl ecx, 2
add ecx, offset threads1
mov edx, ecx
mov ecx,
add edx, 4
mov edx,
mov edi, crcorig
mov esi, tempc
mov eax, fsizec
push edx
mul ebx
pop edx
add esi, eax
mov ebx, esi
add esi,
sub esi, 4
@@: cmp , 0
jne @nocol
push fsizec
push ebx
call getcrc
inc ecx
mov , ecx
cmp ecx, edx
je @nocol
cmp eax, edi
jne @B
dec ecx
mov collision, ecx
@nocol: ret
crccollision endp

getcrc proc uses ebx ecx edx esi edi buffer:DWORD, buffersize:DWORD
mov ecx, buffersize
mov edx, buffer
xor eax, eax
dec eax
@@: mov ebx, eax
shr eax, 8
mov esi,
xor ebx, esi
movzx ebx, bl
mov ebx,
xor eax, ebx
inc edx
loop @B
not eax
ret
getcrc endp

crcgen proc uses eax ebx ecx edx
mov ebx, 0EDB88320h
xor ecx, ecx
outter: mov eax, ecx
mov dl, 8
inner: push eax
and al, 1
or al, al   
pop eax
jne fail
shr eax, 1
    jmp pass
fail: shr eax, 1
xor eax, ebx
pass: dec dl
jne inner
mov dword ptr , eax
inc ecx
cmp ch, 1
jne outter
ret
crcgen endp



start:

call crcgen

invoke CreateFile, offset filenameo, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
or eax, eax
je @err1

mov hfileo, eax

invoke CreateFile, offset filenamec, GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
or eax, eax
je @err1

mov hfilec, eax

invoke GetFileSize, hfileo, NULL
or eax, eax
je @err2

mov fsizeo, eax

invoke GetFileSize, hfilec, NULL
or eax, eax
je @err2

mov fsizec, eax

invoke VirtualAlloc, NULL, fsizeo, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE
or eax, eax
je @err3

mov tempo, eax

mov eax, fsizec
add eax, 4
shl eax, 2

mov falloc, eax

invoke VirtualAlloc, NULL, falloc, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE
or eax, eax
je @err3

mov tempc, eax


invoke ReadFile, hfileo, tempo, fsizeo, offset bytesread, NULL
or eax, eax
je @err3

mov bytesread, 0

mov edi, tempc
add fsizec, 4
mov esi, 4
@@:
invoke ReadFile, hfilec, edi, fsizec, offset bytesread, NULL
or eax, eax
je @err3
invoke SetFilePointer, hfilec, NULL, NULL, FILE_BEGIN
add edi, fsizec
dec esi
jne @B

push fsizeo
push
call getcrc
mov crcorig, eax


mov edi, offset thread1
mov esi, offset tarray
mov ebx, offset threadid1
mov ecx, 4
@@:
push ecx
invoke CreateThread, NULL, NULL, addr crccollision, edi, NULL, ebx
mov , eax
pop ecx
add edi, 4
add esi, 4
add ebx, 4
loop @B

invoke WaitForMultipleObjects, 4, offset tarray, 1, -1

mov ecx,
bswap ecx
invoke wsprintf, offset output, offset format, ecx
invoke MessageBox, 0, offset output, 0, 0

invoke VirtualFree, tempo, 0, MEM_DECOMMIT or MEM_RELEASE
invoke CloseHandle, hfileo
invoke VirtualFree, tempc, 0, MEM_DECOMMIT or MEM_RELEASE
invoke CloseHandle, hfilec

invoke ExitProcess,0


@err3:
invoke VirtualFree, tempo, 0, MEM_DECOMMIT or MEM_RELEASE
@err2:
invoke CloseHandle, hfileo
@err1:
invoke MessageBox,0, offset error, 0, 0
invoke ExitProcess,-1
end start
Posted on 2010-03-29 18:47:42 by paradox
i had to multithread it because on my quad core, windows(xp) would only assign a single processor core per thread.
Yes, that's how multi-core systems work? You can't magically "run a thread on multiple cores".

crccollision proc:
You pushad unconditionally, but popad happens conditionally (only if you have a collision). You don't need to pushad/popad anyway, the calling convention is EAX/ECX/EDX=scratch, EBX/ESI/EDI=preserve.

You run this proc from multiple threads, but write to a single global "collision" variable - bad. Even worse, the thread modifies the memory buffer.

What's with the Sleep() calls after the CreateThread() calls? Pretty senseless - at least once you rewrite your code to be threadsafe ;)
Posted on 2010-03-29 23:11:31 by f0dder
fodder, yep you nailed the problem

its ugly but now its thread safe, it didn't click that i had 4 threads writing to a single global dword.

it wasn't collision that was causing the problem, it was

push fsizec
push tempc
call getcrc

all 4 threads were writing to tempc+fsizec

collision should only be written to by a single thread where the collision happens then all the other threads should exit.

i was trying the sleeps to see if it was a problem with thread creation.

to be honest i have zero experience with threading, this is the first piece of code ive needed to thread.
Posted on 2010-03-29 23:52:39 by paradox
Each thread is *reading* the tempc and fsizec variables, not writing to them. This isn't a problem. However, each thread is writing to the memory buffer *pointed to* by tempc - and this is a no-go, you need to duplicate the buffer per-thread since you're modifying it.

collision should only be written to by a single thread where the collision happens then all the other threads should exit.
This requires some amount of additional logic, and won't be worth it unless each thread is expected to run for a fair amount of time. The basic idea would be running your inner loop for X iterations, check a global "hasCollisionBeenFound" flag, and continue the inner loop if the flag isn't set. Some people would claim TerminateThread is an alternative, but that really is equivalent to dropping a tactical nuke.
Posted on 2010-03-30 02:04:26 by f0dder
Each thread is *reading* the tempc and fsizec variables, not writing to them. This isn't a problem. However, each thread is writing to the memory buffer *pointed to* by tempc - and this is a no-go, you need to duplicate the buffer per-thread since you're modifying it.

------------------------------------------------------------------

thats what i meant :), i updated the code before i posted last time so each thread has its own buffer now.

---------------------------------------------------------------------
This requires some amount of additional logic, and won't be worth it unless each thread is expected to run for a fair amount of time. The basic idea would be running your inner loop for X iterations, check a global "hasCollisionBeenFound" flag, and continue the inner loop if the flag isn't set. Some people would claim TerminateThread is an alternative, but that really is equivalent to dropping a tactical nuke.

each thread is expected to run for a minimum of 30 seconds ( usually 2 minutes ) and is checked at the start of the loop and if != 0 the loop breaks and the thread terminates. is only written to once a valid collision is found so its pretty much the same thing as you suggested.  ill end up re-writing most of it this week so its a lot neater and more stable this was mainly a proof of concept as i haven't done much with threading or hash collisions.
Posted on 2010-03-30 02:25:52 by paradox
Is this a multithreading exercise? ...because crc32 is reversible.
Posted on 2010-03-31 19:18:23 by drizz
Is this a multithreading exercise? ...because crc32 is reversible.
Isn't that only if the message is <= 4 bytes?

Injecting/fixing data to the stream to make the CRC match != reversible :)
Posted on 2010-04-01 02:13:18 by f0dder
anyways, all it does is appends a dword to the modified file, increments the dword then checks the crc against the original crc and loops till a collision happens.
Injecting/fixing data to the stream to make the CRC match != reversible :)

Sure, you can also append a dword to make the CRC match.

Here's a tuto
http://www.codebreakers-journal.com/downloads/cbj/2004/CBJ_1_1_2004_Anarchriz_CRC_and_how_to_Reverse_it.pdf

I've attached my source code and an example.
Attachments:
Posted on 2010-04-01 11:03:42 by drizz

Here's a tuto
http://www.codebreakers-journal.com/downloads/cbj/2004/CBJ_1_1_2004_Anarchriz_CRC_and_how_to_Reverse_it.pdf


Heh, small world.
Anarchriz was in my class when he wrote this paper. He was a friend of mine. I think I'm actually one of the guys who proofread it at the time :)
Posted on 2010-04-01 15:29:04 by Scali