Saturday, February 22, 2014

Extending The Basics

Hello All!

Sorry for such a lengthy delay in the release of this tutorial. I am currently modifying my schedule right now, but once things are worked out I should be able to roll out tutorials in a consistent manner. I'll give details on that when I get everything worked out =)

OK. Let us begin tutorial four. In this tutorial we are looking to practice what we previously learned in the first three tutorials as well as extend our knowledge on assembly. It is highly recommended to do the first three tutorials I released to follow along easily.

Step 1. The Crackme we will be using for this tutorial is called Keygenme1 by Sashx41. Like in the previous tutorials go to and login. Click on advanced search underneath the Crackme search on the left side of the website. Select the following options for search:

Search Options

Step 2. When the results show, scroll down a little and look for Keygen #1 by Sashx41. This is the Crackme we are looking for. It should be the third or fourth one.

Download this one

Step 3. Unpack the zip that is storing the Crackme and go ahead and open it in Ollydbg. Like our previous tutorials Ollydbg paused the program at its entry point.

Opened and Paused.

Step 4. OK our strategy from the previous tutorials has not changed. We are going to run the program and get a feel for it. Remember, the purpose of this step is just to scout around for juicy details. So let us go ahead and run the program.

Program Opened and Running

Step 5. When we run the program we are presented with three lines of text; something about the keygen and then two lines about how we are to move to the next step. The first of the two lines says to enter a name, and the second line says that the name must be 8 characters  or greater in length. I don't think everyone was born with a name that exceeds or meets 8 characters, but let us make one up and enter it ;)

Our name entered.

Step 6. So with our real name entered the program allows us to move to the next step. In this next step it asks us to enter a password. So let us enter our secret password:

Password Entered

Step 7. Yes. We will never give up on hoping to get the password correct on the first try! This marks the end of the program as there is nothing else to do. So our next step in our strategy dictates that we search the program for strings. So restart the program and load up the strings window. Recall, to load strings: 1)  right click in disassembly window, 2) Search for,  3) All referenced strings.

Luckily for us there aren't a lot of strings in the window. I believe this is the only tutorial we have done so far that has an extremely small number of strings. But that's good. This makes our job so much easier. So like before let us look for something that looks like the 'goodboy' message. The string "Right password! You made it! Gratz, now upload your solution." seems closest to a goodboy message, so go ahead and double click on that one.

Text Strings Window

Step 8. Here is how Ollydbg should look once you double click on the goodboy message in the strings window.

Goodboy Message Double Clicked From Strings Window

Step 9.  So we can see in the disassemble window that the goodboy and badboy message are a few lines away from each other. This makes me think that somewhere above the goodboy message there is code that is determining which message should be displayed. So what I am going to do in this instance is look for the little arrow that is pointing right in the machine code column. In the below picture I have a line selected that shows an arrow on it.

Spotting a JMP

Ollydbg will sometimes help you with where JMPs lead to. This assistance is useful in this scenario because this code is very simple and we can quickly determine a place for testing. So if you click on the line that is selected in the picture, you can see that Olldbg shows us that a JLE takes us to this location. (Remember that JLE is a variation of JMPJNE, JLE, JGE, JZ, and a bunch of otheres that begin with the letter J)

Step 10. We are going to use this location as a starting point to test the code and understand it a little. We could of course just start reading the code at this point, but seeing it run is somewhat more helpful since that can be faster then reading. And of course our assembly at this point isn't all that great =) So let us drop a break point on the line that has the JLE on it.

Drop a breakpoint here.

Step 11. Let's play with the program now! Go ahead run the program and perform the program duties until we hit the break point.

Break Point Activated

Step 12. Nice. Notice that the jump is not taken. The area that shows you this is where the big black Microsoft paint arrow in the above picture points to. So far this tells me that our random input doesn't affect this condition. This means that the badboy message is not going to be displayed by some incorrect guess. From this point on we are going to have to do some more research to see how this program works. So let us just F8 (step over) our way through.

We will quickly find our self in a loop. We can tell because Ollydbg has drawn a black line that is inside the assembly column. The picture below shows which line I am talking about.

The Loop

Inside this loop there is a problem. There is a JNE that points to an area in code that is below the goodboy message. The area below the goodboy message just so happens to be the code for showing us the bad message. See the below picture for reference.

This line will spell our doom

NOTE: The picture points at the line that the JNE takes us to. I'm not referring to the PUSH ECX assembly code. It's the red line you are looking for!

OK. So at this point in the tutorial I am going to branch off. There are many different ways to solve this Crackme from where we are now. I am going to show you some of these solutions with each being a different degree in difficulty. We will start with the easiest then work our way to the more involved solutions.

The Easiest Approach ---------------------------------------

So the easiest way of solving this Crackme will be a simple patch to the JLE that exists above the loop. Instead of entering the loop we can simply direct the program to the code after loop exit and we will see the goodboy message. Let us try this.

Recall the first break point we set:

Our first Break Point

Changing the program instruction at this point will be the easiest way to solve the Crackme. We can simply change the JLE to a JMP that lands us on the code immediately after loop exit.

Easy Jump

The last line of the loop is a JL SHORT. The line immediately after this is the line after loop exit. All we must do is point our jump to this location. As you can see in the above picture I changed the assembly of the JLE SHORT 01011227 to JMP 01011212. The 01011212 is the line after loop exit.

After changing the assembly, continue (run) the program and it will yield this result:


A Slightly More Involved Approach ------------------------------------------------

Instead of changing the assembly line before the loop in this approach we are going to modify the jump line inside the loop. The reason I am showing this approach (even though it is inefficient) is because it will teach you more about assembly/programming. And we all know that in order to be a good reverse engineer you need very good knowledge of assembly.

I am going to quickly go over the solution then describe in detail why it works.

Step 1. Restart the Crackme in Ollydbg.

Step 2 If you added the patch from the first approach, remove it by selecting View > Patches > (right click on entry in patch window) Restore code.

Step 3. Drop a break point on the JNE SHORT which is inside the loop.

Break Point Inside Loop

Step 4. Now let us change the line that the break point is on. Double click the line and make it a NOP.

Step 5. Remove the breakpoint from the line and then continue (run) the program. T

Step 6. Success!

Successful NOP

Now that we see the magic let us introduce the science to understand how it works.

The Loop Assembly
So all the science is in this loop. If we understand this loop, we will understand the password comparing process. We will even find the real password if we understand this loop (that will be the next approach).

Starting at the top of the loop is


Let's break the line down piece by piece. Recall the structure for writing an assembly instruction:

instruction argument1, argument2

For instruction we have MOV. Quick lesson recap: the mov instruction places what is in argument2 into argument1. This means that whatever is in BYTE PTR SS:[EAX+ESP+10] will be moved into CL

For argument1 we have CL. This is a new piece of assembly that hasn't been introduced in any of the previous tutorials. So let's go through what this CL is. Warning: it will be a long journey to get there!

Recall in the second tutorial that we learned about the EBP register (which stands for the extended base pointer). The EBP register held data for the program to utilize. We can see what the register is holding by looking at the registers pane in the top right of Ollydbg.

You might also notice in that same pane a few other words that begin with the letter E. That's because there are multiple registers a program can use. You know about the EBP already. Let's name the other ones:


Each of these registers are used to hold data or some type of data throughout the programs lifespan. We won't go into detail for all of them because that will be to hard to remember for now. But what we do need to cover is that some registers can segment themselves into smaller pieces.

Each register is 32 bits in length, and we access the entire register via its full name e.g: EAX. However, if we wanted to access just 16 bits of EAX we use AX. And if we wanted to access 8 bits of the AX we use AL or AH. This can be seen in the naming; EAX means extended accumulator register, AX means accumulator register, AH means accumulator high, and AL stands for accumulator low.


MOV EAX, 0FCA1240 - moves 0x0FCA1240 into the register
MOV AX, 6F4A - moves 6F4A into the AX register
MOV AH, 6F - moves 0x6F into the upper 8 bits of the AX register
MOV AL, 3 - moves 0x3 into the lower 8 bits of the AX register

OK. Let's bring it all together now. We have a value being moved into CL. The CL is counter lower register. Its the subset of the CX register who is the subset of the ECX register. So we are moving 8 bits of something into this register.

Notice in the picture below we have 6F in the ECX register. 6F also fills the space for CL. Notice that CH is 00, CX is 006F, and the entire ECX register is 0000006F.

6F is in CL

NOTE: For argument2 its highly likely that your memory address and value that you will be seeing will be different. You should be able to follow the steps along easily and replace the values I have here with the ones on your computer. 

Now lets go over argument2. This is what is being pushed into the CL register. The argument reads: BYTE PTR SS:[EAX+ESP+10] Although there is a lot of stuff in it, it is very easy to break down. By seeing the SS: we know it is referencing the stack segment. This means our eyes want to be on the stack frame panel in the lower right section of Ollydbg.

The Stack aka SS:

The BYTE PTR tells us that we will be pulling a byte sized value off of the stack. What is inside the brackets tells us where on the stack we will be pulling the byte sized value. Inside the brackets we have EAX+ESP+10. If we add that up, it will give us the address of where to remove the value from. So let's do the simple math real quick. Looking at your registers pane (see above image), add the values in the corresponding registers:

EAX at the moment this program is running is 0.
ESP at the moment this program is running is 00BFF730.
And 10 is 10.

So load up your windows calculator and set it to programmer view.

This is the location on the stack we need to get the value from. BYTE PTR:SS[BFF740]. So look for BFF740 in SS: where SS: is the stack, and remove a BYTE PTR from the location.

BFF740 is equal to 36373839
We can see in the picture above that BFF740 is equal to 36373839. Since we only want a byte sized value (A byte is 8 bits. A byte is equal to two hexadecimal value e.g. F = four bits and FF = one byte) , we remove the 39 from the very right.

If we step-over, we see CL is now 39.

This concludes the explanation for the MOV CL, BYTE PTR:SS[EAX+ESP+10]. We can verify that it moves the value 39 into CL by stepping-over onto the next line and viewing the ECX register. The above picture shows this. Notice Ollybdg is now on the line after MOV CL, BYTE PTR:SS[EAX+ESP+10]. This means the previous line has been computed.

Now that was a lot of information. I hope this isn't overwhelming you! For the rest of the lines inside the loop I am not going to write a detailed explanation for those. I will do so on the next approach. Instead what I am going to write is how they work.

So what happens next in the loop is very simple. We are going to compare the value that was found and placed into CL versus another value on the stack (EAX+ESP+210). If these values match, then we are going to increment a counter (the counter is EAX) and remove another byte value from the stack and push it into CL. We won't be removing the same exact value from the stack but rather the number to the left of the one we had just used (the 39). We are going to repeat this until either the comparison fails, or the counter reaches the value of EDI.

If the comparison fails (CL does not match the value) then we are going to JUMP to the badboy message. This means the JNE SHORT inside the loop will be activated. Recall JNE means jump if NOT equal.

If the loop completes, the program will automatically run the path of showing the goodboy message.

From this information we can find an exploitable flaw. That is, as long as the JNE SHORT is never called then the program will always display the goodboy message. This is good information. This explains why the program gives the goodboy message when we placed a NOP in place of the JNE SHORT.

OK. I am going to cut the tutorial here and place the next approach in the upcoming tutorial. I really wanted to place it here, but I feel this is so much information for one to manage. On top of that this tutorial is already very lengthy. I do need to consider that you guys have other things to do =)

So in the next tutorial I will write about how to uncover the password, so that we do not have to patch the program. If you want some homework, then see if you can discover the password mechanism on your own, and enter an explanation in the comments below. Remember, the password mechanism is the loop itself.

Thursday, January 23, 2014

Patching The Executable

Greetings everyone and welcome to the third tutorial of the reverse engineering for newbs series. Today we are going to cover... patching! But you knew that already =)

NOTE: The knowledge from tutorial 1 & 2 is not needed for learning this technique; HOWEVER, if you want to be a good reverse engineer, then you will want to learn what was covered in tutorial 1 & 2. If you find yourself completely lost in this tutorial, do not feel that reversing isn't for you. Reading tutorial 1 & 2 will help you understand this one.

OK. We are going to use the same exact Crackmes that we used in both tutorial 1 & 2. Here is a link to tutorial one if you need instructions on getting the Crackmes. Because this tutorial is supposed to be stand-alone I will go over the steps covered in tutorial 1 & 2 to reaching the string we need. Now let us begin.

Step 1: Open ReWrit's Crackme #1 inside Ollydbg. Your Ollydbg should look like mine from the picture below when the Crackme is successfully loaded.

ReWrit's Crackme Loaded

Step 2: The first thing we do every time we want to solve a Crackme is run it. So let's go ahead and run the program to scout for juicy information. We have four ways to run the Crackme. First: run the Crackme outside of Ollydbg =) Second: click on the play icon in Ollydbg which is located underneath the 'w' in View on the menu bar. Third: select Debug from the menu and hit run. Fourth: hit F9 on your keyboard.

Step 3: Okay so the Crackme is running! Let us go ahead and look around for some juicy stuff. We immediately notice that the Crackme is a console app, so that kind of takes away the need to search around. Since we only have one possible path to go at the moment, let us tread along.

We are asked to enter a password, but the program says that the password is NUMBERS ONLY. That is a very important clue. It is not every day that a Crackme will tell you how the password (or answer) is shaped. So if the author of the Crackme is not lying then we already have discovered an important clue just from running the app. The password is only in numbers. Let us enter the password then =)

I went ahead and entered my password:


And you can see I was wrong. It is always worth the try! OK from this point on it seems we can't do anything else, so let us go ahead and restart the program.

Step 4: Restarting is as easy as switching to Ollybdg and hitting Ctrl + F2. You may also click on the icon to the right of the open file icon underneath the menu bar. It is the one with two arrows pointing to the left. And lastly you can go to Debug > Restart from the menu.

Step 5: OK we got a feel for the program. Now let us start cracking it. Right click in the Disassembler - Main Window, hover the mouse over Search For and select All Referenced Strings. Remember one of the best starting points for tackling a Crackme or any program is the strings of the program. A lot of  potentially program breaking information can be found in the strings.

Right click in the Disassembler - Main Window

Search for All Referenced Strings

Ollydbg will bring a window to the front that is titled Search - Text Strings referenced in ReWrit's_Crackme#1. See the image below for a reference.

Strings Window

We want to select a useful string here. If you read tutorial 1 & 2, this is all repetitive to you, and that must be a little boring. But these steps will have to be replicated over and over again in every Crackme we solve. You will see =)

Step 6: So we are going to look for a string that will point us closely to the function that determines if the password we entered is correct or incorrect. Let us go ahead and locate the "Correct, good job!" string. Once you find it double click on it. Ollydbg will select a line of code that loads the string.

Select this string

Ollydbg brings you here
Step 7: OK patching time. Do know that I am considering you have close to zero understanding of what you see on the screen. The only goal of this tutorial is to show you what patching is. Later on we will learn all the tiny bits piece by piece. Trying to teach you everything you see on the screen will be overwhelming.

So if you read the previous tutorials you will know that exactly five lines above the line Ollydbg dropped you on is the line that determines if the password is correct or incorrect. In tutorial one we flipped the Zero flag after this line computed in order for us to force the program to give us a success message. We did this by setting a break point on the line below (four lines above the one Ollydbg dropped us on), letting the program run, and after we entered our password we flipped the number to the right of the giant Z in the registers pane.

This method allows us to always have the "correct" password even though it truly isn't correct. The only downside to this method is that we must always flip that zero flag every single time in order for the program to pass through. What we are going to do now is make the program give us a success message EVERY TIME without having to flip that zero flag. This is called patching.

Now there are many ways we can patch this program .We will go over one, and I will leave it as homework for you to find the other ways to patch the program. The one we are going to use is the most common means of patching.

Step 8: So exactly four lines above the line Ollydbg dropped you on (that is, four lines above the line that says ASCII "Correct, good job!") we want to double click on the assembly code associated with that line. Refer to the pictures to locate the assembly code column as well the line I am writing about.

assembly code column

Select this line and dbl click in assembly code column

Assemble Window Loaded
Step 9: So now you have the assemble window opened. This window will allow us to change the code of the program. The only restrictions you have when changing code are these: we will only be allowed to change the line we selected, and the new code size can not exceed the size of the line of code already there. If we read the Machine Code column, we can see the bytes "75 36". This means this line is two bytes long. We cannot write code in here that exceeds two bytes.

But no worries. The most common patching technique only requires one byte!

In the assemble window that is open enter the instruction "NOP". This is in the infamous NO OPERATION instruction. This instruction simply tells the program to do nothing. Underneath the hood the NOP is a "XCHG EAX, EAX". That means swap the EAX register with the EAX register. Essentially, it means do nothing.

Entering NOP into assemble window

Hit assemble. Then hit close.

NOPs added

Step 10: Notice the assembly code and machine code columns now have text highlighted in red. This means that this code is patched. Also notice that there are two lines that say NOP. Didn't we just have one line? The previous instruction that was there was two bytes in length, and since a NOP is one byte in length the program must fill the remaining empty bytes with one byte instructions that do nothing. In other words, it will fill the remaining space with NOPs.

Let us go ahead and test this program. Go ahead and run the program, and enter whatever password you want =)


Good job! The patch we entered works. Simply NOPing out the jump instruction (explanation on this later) the program gives us the good message.

Step 11: OK let us restart the program now. When you restart the program, the patch that you applied is removed. The original code is set back in place. Ollydbg does save our patches though, so we can reapply them. Let us re-apply the patch we made to the program.

In the menu, click on View and then click on Patches.

The Patches
Like the image above Ollydbg will bring a window forward called Patches. You will notice that there is only one item in this window. One of the columns is titled Original Command, and the lone item that exists in the patch window has a value of  "JNE SHORT 00401594" for this column. To the left of this column is NOP. This is the line we patched.

Right click on this item and hit Apply Patch.

Apply the patch

You will notice that Ollydbg changes your Disassembler - Main Window to the location of the patched line. It will also highlight the patched lines.

Step 12: If both of the NOP lines are not highlighted, go ahead and highlight them with your mouse. Right click anywhere in the highlighted area, and select Edit > Copy To Executable.

Copy to Executable.

You might get an annoying window pop up from Ollydbg that looks like this:

In our way of success
Ignore the instructions from the window. Click OK. In the new window which has the two NOPs at the top, right click in this window and hit Save File... 

Save File!

Ollydbg will continue to block you from your success with another window titled File Changed.

Just let me save!

Click Yes on this window. Ollydbg will give you the Save File As windows dialogue now. This will save the new executable as whatever name you give it with the new instructions patched in. Go ahead and save it somewhere, on your desktop, where ever. Just be sure to have the Save as Type selected to Executable file or DLL. Run the newly patched program and see your success =)

Extra material: In order to become a good reverse engineering, it is imperative that you understand assembly code. You must know what the program is doing at a selected line. I am going to cover why patching that line that we did works. This will be a lesson in assembly language.

If you followed the first two tutorials then you know that the line above the one we patched is the line that determines if the password is correct or not. It compares the password we entered against the actual password. If the password is not the same as the one the author wrote, then the Z(ero) flag in the registers pane is set to 0.

Although the program sets the Z(ero) flag to 0, it has no idea what to do with this 0. The comparing password line does one thing and one thing only. It compares the password entered. It does not know what to do if the password is right or wrong. The line that follows determines what the program should do with the zero flag (the result of the compare).

JNE SHORT 00401594

This is the line that reads the zero flag, and makes a decision of what the program should do. The main instruction in this line, the JNE, reads JUMP IF NOT EQUAL. So this line will jump if the previous result is not equal to whatever it was comparing (which means the zero flag is set to 0). The short means it will jump a short distance from this line (either 129 bytes forward or 126 bytes backwards). And lastly the 00401594 is the address to jump to if not equal. 

So if you enter an incorrect password, you will be sent to the line 00401594


We can see in the picture above that the selected line is on address 00401594. If you look a little down from the selected line, in the comments column, you will see "Wrong!". This is where the program loads the bad message if you failed to guess the correct password. We saw that message load when we were scouting the program in step 2.

So here is an overview of the if structure the program has:

Pseudo Code

If the password is equal then it will fall through and print "Good job!" to the console. If, on the other hand, the password is incorrect, the program will display "Wrong!" to the console.

Here is pseudo code for what our patch did:

ComparePassword func is useless
We removed the entire if structure from the program, so no matter what the ComparePassword() function returns we will still show "Good job!".

That wraps up this tutorial. If you have found other means of patching the executable, post them here for all to see =) Also, I am expecting to write tutorials for much more difficult Crackmes as well  tutorials on iPhone Cracking.

Please leave any feedback here too! I appreciate all comments good or bad. Have a good day!

Thursday, January 16, 2014

Moving Forward

Hey guys,

I want to know what kind of tutorials you want to see. What I have planned currently is: teaching different methods of beating a crackme, solving more difficult crackmes, and tutorials on iPhone cracking. Please tell me the kind of tutorials you want to see? All suggestions are welcome.

Oh. And.

Follow me so we can keep in touch easier:

Facebook Fan Page

Friday, January 10, 2014

Building off of exercise one

I hope tutorial one wasn't overwhelming for you. In this tutorial we are going to explain some of the things you saw in the first tutorial. We are also going to find correct password, so we can enter successfully every single time.

Recall the breakpoint that we set on the line that I said compares if the password entered is correct or incorrect. Well I was lying about that being the line that compares if the password is correct or not. It is the line above that determines if the password is right or wrong. We can see this by reading what is inside the third column. Let's see two photos before some more explaining.

The password checker

Column names

The assembly code column shows us what the program is doing. This is what we read when we are reversing  programs. I do not expect you to be able to understand any of the code that is in the column. Learning to read that code will come with time. Do keep in mind though that reversing programs REQUIRES one to know assembly. If you do not learn assembly eventually, you will not be able to reverse programs like you want to. You can solve many low level Crackme's with very little assembly understanding, but that is the furthest your skill will take you.

Let your first lesson in assembly start today. We'll dissect the password checker. (The line in the red box from the photo above). It reads:


The first word in the assembly line is always the instruction. In this case the word CMP is our instruction. Everything that follows from the first word up until the comma is argument one. Here argument one is DWORD PTR SS:[EBP-4]. Everything after the comma is argument two. Argument two in this case is 7F97E56C. Thus the structure:

instruction argument1, argument2

The CMP instruction compares argument one and argument two for equality. If they both are equal then it sets that number next to the Z (from the previous tutorial) to a one. If they are not equal, then it sets the number next to the Z to a zero. This explains why when we double clicked the number next to the Z in the previous tutorial, the application told us we got the password correct. I'll give a series of steps of what happened in the last tutorial, and then I will explain argument one and argument two a little bit.

Here is what happened last tutorial. This should explain why we solved the application so easily.

1) We set a break point underneath the password checking line
2) We ran the program and entered some bogus password
3) The program runs every line of code until it reaches the break point. This also means it ran the line that determines if the password is correct or not. The result of the password checking line was setting the Z number to a 0 - it was not equal.
4) We manually changed the programs password checking result by changing the zero into a one.
5) We ran the program as if the password was correct all along, allowing us to see the "Correct, Good job!" response.

The explanation for what argument one and argument two are will be difficult to understand but that's fine. We will go over the items upcoming a few times in the tutorials to come. Argument one, or DWORD PTR SS:[EBP-4] is a reference to a location on the stack. Recall in tutorial one the image with the titles of the panels. The stack is the lower right panel.

The stack is the lower right panel

We know it is referencing the stack because of the EBP-4. EBP stands for extended base pointer. Like a variable in programming, the EBP holds data for the program to use. In assembly we call these variables registers. The EBP register stores a location in the stack, so when we say EBP-4 we mean: take the location in stack that EBP is holding and subtract four from it. Let us see what value EBP is holding when the application hit the break point that we set from the previous tutorial.

EBP holds 0028FF38

I used the picture from the last tutorial and added some more mspaint art to it. This is to give you a reference of which point I'm talking about. We can see EBP holds the value 0028FF38. If we look at the stack, we can find that value in the purple boxed area. The same way the EBP register can store data, so too can the stack. At the location 0028FF38 in the stack is the value 0028FF74.

Remember that argument one from the password checking line is [EBP-4]. So we have to subtract four from the EBP to find location the line is using. So if we subtract 4 from 0028FF38 we get the value 0028FF34.
Note: the value 4 and 0028FF34 is in hexadecimal. You can always load up the windows calculator to do the subtraction when the subtraction is no longer simple.

So we can see that [EBP-4] is holding the value 3F. We should open the windows calculator, set the view to programmer, and select hexadecimal on the left side. Enter 3F into the calculator and then select decimal on the left side. The value will be 63. This is the password that I entered. I ask that you also check the value of EBP-4 with the password you entered.

Do you see where this is going? :) If you don't, it is OK. We will learn.

Recall the structure:
instruction argument1, argument2

We have a CMP instruction which means check if argument1 and argument2 are equal. So if argument1 is the value of our password, then argument2 is the password of the application. We can prove this by taking argument2 and entering it into the program.

Recall the value of argument2, 7F97E56C. If we enter that as hexadecimal into the windows calculator and set it to decimal, we get the value

So the password of the application must be 21400661100. Let us verify this.