The Flood Waters Reveal the Code! Making a code generator of our own |
||
Date 12/27/00 |
by
Sojourner
|
|
There is a crack, a crack in everything. That's how
the light gets in.
|
||
Rating |
()Beginner (x )Intermediate
( )Advanced ( )Expert
|
This one is a little
different from what we're used to working on, but it is fun because we get to
learn something new and we get to solve our problem with the information supplied
by the prog, as is so often the case.
|
This is a Photoshop plugin called Flood that makes some very nice water-like additions. I hope you like this as it is a new method of learning that I haven't done yet.
|
w32dasm 8.x--your choice of flavors
hex editor not needed!
new!- 32 bit assembler- I used MASM32 because I just downloaded it- use whatever
you want
|
Just go to this site and then download what you need.
|
What to do - 1. Make a little assembly prog to tell us the code and use w32dasm to see it. 2. Or let the prog do a little work to generate the code for us.
|
Alright, this is going to be fun because we are going to do something totally new with my writings. Go ahead and download the Flaming Pear Flood or LunarCell or what ever you want from their site. Their schema is much the same. Now disaasemble in w32dasm. C'mon, we got things to do already. Now have a look around from inside of Corel Photopaint or Adobe Photoshop and then call forth the plugin from there. Try to register it and of course you'll get an error. Now, this is the Flood part down below. As you'll see, if we're successful with our serial number, Flood will be happy and register us. What is really going on is a series of complex mathematical sorcery to determine if we indeed do have a right serial number. I hope to show you that there are several "right" numbers. We will actually make the assembly prog that will show us these "right" numbers, also. At least, I'll give you the basic code you need to do this. Now , these first six instructions starting with 1000FE5C and ending at 1000FE73 are merely prepping the scene and qualifying our input number. For instance, the first test instruction is seeing if we have entered anything at all in the blank. If not, then out we go. If we have put something there, it checks the high byte, ie ch of the cx register with a mask of 10H or 16d. If we pass that filter, then on we go to the cmp at 1000FE6D. If our number is greater than 000F4240H or 1,000,000d, then we may have a chance to go on. I actually disassembled Photoshop and ran the Flood plug through there. I had also run LunarCell, too. Anyway, I suppose I should say that there are at least a couple of ways to do this that I will tell you about. I actually arrived at this through trial and error after not wanting to just make a bunch of nops to force the prog to accept whatever I give it and also after examining the checking mechanism below. Alright, one way to do this is kind of a force, but it uses the program's own code to help you if you can't or won't do assembly. Before I describe this way, let me elaborate the checking mechanism and help clarify what I've learned in order to help you, too. Starting at: 1000FE79 mov eax,ecx, we see that the value loaded into ecx, which just happens to be our serial number is placed into eax. Why? Because it is being set up for some mathematical computations such as the idiv, and idiv works on the eax or ax register only. Now, once that is done, 91h or 145d is loaded into the edi register in preparation for the actual value used as the divisor on eax. Next an unusual opcode, the cdq is used. CDQ expands a double- word into a quad word and places the upper 32 bit value in edx. Here we will see it being used to place remainders into the edx register to be acted upon. The remainder on the first cdq-idiv combo is arrived thusly: let's say you enter in the number 2578907 in decimal. The cdq expands 2578907 into edx starting with the 32nd bit. It's very much like the cwd or the cbw opcodes which fill up their respective register slots with the appropriate bits. In this case edx becomes zero. Now the idiv opcode is performed by dividing our number in eax by the loaded value in edi. 2578907/145 = 17785.56552 Immediately the remainder or .56552 is multiplied by 145, so we get some number in edx or 81.999994 = 82. Next step- at 1000FE83 our original number is reloaded back into eax for another round. Look at what's being used as our start point for our divisor, the remainder value in edx 82 is then added to 16227d to become our next divisor. The new divisor is: 16227 + 82 = 16309. So 2578907/16309 = 158.1278435 Strip off the quotient and the remainder is .1278435 which is multiplied then by 16309 to be 2085 and not 1Bh or 27d. So our number will fail the test friends. Pretty slick, huh? If you are able to single-step down through the code running w32dasm, then you can watch these changes taking place as I did. So, now we know the checking routine how do we fix this baby? Two quick ways can be shown easily I believe. At our last checkpoint 1000FE93 7566 jne 1000FEFB, we can go in and reroute the jne to go back to 1000FE73 and inc ecx, which contains our original number and continue to cycle through this loop until we get at least one good number. And believe me, eventually we will get a good number. Now if you wish to catch this number just put a breakpoint at 1000FE95 and look into ecx at that point. The other way is to strip the relevant code from here and place into a 32 bit assembly program. I used three distinct variables to hold three individul distinctly unique numbers generated in this fashion. You could also make an array to hold the numbers. It doesn't really matter how you do it. The code works no matter as long as you use the 32 bit assembler. You must supply a starting number that is greater than one million. I did this as a variable double word and my storage variables were double words, of course.
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:1000FDDE(C), :1000FDF0(C) | :1000FE5C 85C9 test ecx, ecx <--Here :1000FE5E 0F8497000000 je 1000FEFB :1000FE64 F6C510 test ch, 10 :1000FE67 0F858E000000 jne 1000FEFB :1000FE6D 81F940420F00 cmp ecx, 000F4240 = 1,000,000 :1000FE73 0F8C82000000 jl 1000FEFB :1000FE79 8BC1 mov eax, ecx :1000FE7B BF91000000 mov edi, 00000091 = 145 :1000FE80 99 cdq :1000FE81 F7FF idiv edi :1000FE83 8BC1 mov eax, ecx <--Reloads our original value!! :1000FE85 8BFA mov edi, edx :1000FE87 99 cdq :1000FE88 81C7633F0000 add edi, 00003F63 = 16227 :1000FE8E F7FF idiv edi :1000FE90 83FA1B cmp edx, 0000001B = 27 :1000FE93 7566 jne 1000FEFB :1000FE95 8B4604 mov eax, dword ptr [esi+04] :1000FE98 56 push esi :1000FE99 8B500C mov edx, dword ptr [eax+0C] :1000FE9C 8B02 mov eax, dword ptr [edx] :1000FE9E 8988FC2D0000 mov dword ptr [eax+00002DFC], ecx :1000FEA4 8B4E04 mov ecx, dword ptr [esi+04] :1000FEA7 8B510C mov edx, dword ptr [ecx+0C] :1000FEAA 8B4E20 mov ecx, dword ptr [esi+20] :1000FEAD 8B02 mov eax, dword ptr [edx] :1000FEAF 8988002E0000 mov dword ptr [eax+00002E00], ecx :1000FEB5 8B5604 mov edx, dword ptr [esi+04] :1000FEB8 8B420C mov eax, dword ptr [edx+0C] :1000FEBB 8B5624 mov edx, dword ptr [esi+24] :1000FEBE 8B08 mov ecx, dword ptr [eax] :1000FEC0 8991042E0000 mov dword ptr [ecx+00002E04], edx :1000FEC6 E8B528FFFF call 10002780 * Possible StringData Ref from Data Obj ->"***" | :1000FECB 6830D20110 push 1001D230 * Possible StringData Ref from Data Obj ->"**" | :1000FED0 682CD20110 push 1001D22C * Possible StringData Ref from Data Obj ->"*" | :1000FED5 6828D20110 push 1001D228 * Possible StringData Ref from Data Obj ->"Flood" | :1000FEDA 6820D20110 push 1001D220 :1000FEDF E81C6FFFFF call 10006E00 * Possible StringData Ref from Data Obj ->"THANKYOU" | :1000FEE4 6804D20110 push 1001D204 :1000FEE9 E86274FFFF call 10007350 :1000FEEE 83C418 add esp, 00000018 :1000FEF1 5F pop edi :1000FEF2 5E pop esi :1000FEF3 5B pop ebx :1000FEF4 81C404010000 add esp, 00000104 :1000FEFA C3 ret
The other way is to strip the relevant code from here and place into a 32 bit assembly program. I used three distinct variables to hold three individul distinctly unique numbers generated in this fashion. You could also make an array to hold the numbers. It doesn't really matter how you do it. The code works no matter as long as you use the 32 bit assembler. You must supply a starting number that is greater than one million. I did this as a variable double word and my storage variables were double words, of course. Below is a snippet of the code. You'll need to make it fit your needs. Add your variables, the proper jumps, etc.
mov ecx, Your variable :1000FE79 8BC1 mov eax, ecx :1000FE7B BF91000000 mov edi, 00000091 = 145 :1000FE80 99 cdq :1000FE81 F7FF idiv edi :1000FE83 8BC1 mov eax, ecx :1000FE85 8BFA mov edi, edx :1000FE87 99 cdq :1000FE88 81C7633F0000 add edi, 00003F63 = 16227 :1000FE8E F7FF idiv edi inc Your variable mov ecx, Your variable :1000FE90 83FA1B cmp edx, 0000001B = 27 :1000FE93 7566 jne 1000FE79 That's it everyone. Go to it. Live long and prosper! Enjoy the new millenium.
|
This was a somewhat complex lesson, but worth your brain power to figure things out. If you have any questions please feel free to contact me at jomamameister@yahoo.com
|