Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

can anyone get these lines to work? changing a byte... 1

Status
Not open for further replies.

Trope

Programmer
May 14, 2001
110
0
0
US
sure wont work for me, but it's supposed to.

LPVOID address;
// Get the address of the dword we need to change

_asm mov dword ptr address,offset [myloop+3]

// Ask windows for permission to modify the code
result = VirtualProtect(address,4,PAGE_WRITECOPY,&oldprotect);

// Modify it in assembly.
// This is equivelelent to *(LPLONG)address = 0x87654321
_asm mov ebx,dword ptr address
_asm mov dword ptr [ebx],0x87654321

// All done
result = VirtualProtect(address,4,PAGE_EXECUTE,&oldprotect);

myloop:
_asm mov dword ptr a,0x12345678
 
Yes, MSVC 6.0

Code:
#include <windows.h>
#include <winnt.h>
#include <stdio.h>

int main(void)
{
DWORD a;
LPVOID address;
DWORD oldprotect;
BOOL result;

// Get the address of the dword we need to change
_asm mov dword ptr address,offset [myloop+3]

// Ask windows for permission to modify the code
   result = VirtualProtect(address,4,PAGE_READWRITE,&oldprotect);

// Modify it in assembly.
// This is equivelelent to *(LPLONG)address = 0x87654321
_asm mov ebx,dword ptr address
_asm mov dword ptr [ebx],0x87654321

// All done
   result = VirtualProtect(address,4,PAGE_EXECUTE,&oldprotect);

myloop:
_asm mov dword ptr a,0x12345678


   printf("%lx\n", a);

return(0);
}
 
Ok, now it appears something is going wrong on my machine.

I have VC++ Express and it's not compiling - not compiling in Builder 6 either.

Could you send me the executable to webdevia@yahoo.com (rename extension to .txt) so I can debug it here.

Thanks mingis. I appreciate your help. If you are interested, I am looking for a tutorial on the following , and willing to pay for it --> This is my post on a "pay for answer" type of board which I will not mention...

If you are interested, please email me at webdevia@yahoo.com

Thanks again, mingis.

Trope!

-------------------------- my other post
First of all, I am new to C++. I am designing an application that will operate ONLY if the user has the correct password. Simple enough.

My question is this: How can I prevent the casual 'cracker' from simply disassembling my program and patching the byte that TEST's the valid serial? I realize we cannot 100% prevent my program from being cracked, but I want to discourage the casual cracker - if I can crack my own program, something is wrong!

My program is VERY simple, and will look something like this:

if(validPassword==TRUE){
// Program Continues
} else {
// Program Ends
}

When assembled, may equate to something like this:

99999991 TEST EAX, EAX
99999992 JNE some location
99999993 Good Code Here

Now it is simple cracking-101 to know that all we have to do here is replace address 99999992 with a couple NOP's and the program will work no matter what.

So... I want the program to immediately check the value at 99999992 and if it is a NOP (90h) then I want to change it back , or Quit the program - whatever is easier for you to answer this question with.

Now I will tell you that I have been studying Self Modifying Code for 2 straight days now, and can't even get this simple code to work:

//---------------------------------------------------------
LPVOID address;
// Get the address of the dword we need to change

_asm mov dword ptr address,offset [myloop+3]

// Ask windows for permission to modify the code
result = VirtualProtect(address,4,PAGE_WRITECOPY,&oldprotect);

// Modify it in assembly.
// This is equivelelent to *(LPLONG)address = 0x87654321
_asm mov ebx,dword ptr address
_asm mov dword ptr [ebx],0x87654321

// All done
result = VirtualProtect(address,4,PAGE_EXECUTE,&oldprotect);

myloop:
_asm mov dword ptr a,0x12345678
//------------------------------------------------------------------------

I was just using that code to practice with. But no luck.

Anyways, I am looking for a simple example similar to the way my program will work. If the byte has been changed, quit or change it back (preferably change it back).

Thanks, and anxiously awaiting your answer!

Trope
 
I'm using Watcom 1.1 compiler too, it claimed about line

_asm mov dword ptr address,offset [myloop+3]

- it could not evaluate value of the label.
Try following snippet - it works under Watcom.
Offsets in lines

_asm mov eax, [esp+0x18]
_asm add eax, 0x11

are compiler dependent - should be choosed during debuging in disassembled mode.

Code:
#include <windows.h>
#include <winnt.h>
#include <stdio.h>

void getaddress(void)
{                       
// get return address from the stack   
_asm mov eax, [esp+0x18]   // ---------- compiler dependent offset
}


int main(void)
{
DWORD a;
LPLONG address;
DWORD oldprotect;
BOOL result;

goto setaddress;
back:

   result = VirtualProtect(address, 4, PAGE_READWRITE, &oldprotect);

_asm mov ebx,dword ptr address
_asm mov dword ptr [ebx],0x87654321

   result = VirtualProtect(address, 4, PAGE_EXECUTE, &oldprotect);

goto myloop;

setaddress:
_asm call getaddress // mov eax, eip     could be used instead, if it is legal 
_asm add eax, 0x11    // ---------- compiler dependent offset to the litteral 0x12345678
_asm mov dword ptr address, eax
goto back;
myloop:
_asm mov dword ptr a, 0x12345678

   printf("%lx\n", a);

return(0);
}
 
Hi Mingus,

Thanks for that example, I have studied it extensively.

Is there any way I can talk you in to helping me with this?

Here's what I got:
----------- code start --------------

#include <windows.h>
#ifdef __BORLANDC__
#pragma argsused
#endif

int goodGuyMessage(){
MessageBox(NULL, "Correct Password", "Success", MB_OK);
}

int badGuyMessage(){
MessageBox(NULL, "Wrong Password", "Error", MB_OK);
}

int checkForPatch(){
// HERE IS WHERE I NEED HELP!
// Looking for a NOP at address ?????
// if so, return 1 else return 0
}


// Declare Variables
// 5 = good guy, anything else bad guy
int theFlag = 5;
DWORD targetAddress; // not used here yet

int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{

// The program begins...and we..
if (checkForPatch() == 1){
//uh oh, they patched it. Quit program for now.
// Eventually we will change the bytes back once
// I know what bytes I am looking for!
exit(0);
}


// blah...blah...

// Padding in case we need it? Not sure
__asm nop
__asm nop

// This is where the cracker will want to patch
// so this is the code we are going to need to check
__asm theyWillChangeMeHere:
if(theFlag == 5){
goodGuyMessage();
} else {
badGuyMessage();
}

// Padding in case we need it? Not sure
__asm nop
__asm nop

return 0;
}


AND.. it assembles to this (the part they will patch):

0040124B |> 90 NOP
0040124C |. 90 NOP
0040124D |. 833D A4904000 >CMP DWORD PTR DS:[theFlag],5
00401254 |. 75 07 JNZ SHORT Applicat.0040125D
00401256 |. E8 A5FFFFFF CALL Applicat.goodGuyMessage ; [Applicat.goodGuyMessage
0040125B |. EB 05 JMP SHORT Applicat.00401262
0040125D |> E8 B6FFFFFF CALL Applicat.badGuyMessage ; [Applicat.badGuyMessage
00401262 |> 90 NOP
00401263 |. 90 NOP

SO we see that the address we need to check is: 00401254 and we want to compare those two bytes 75 07 to 90 90, right?

I sure would appreciate some guidance on this. Am I on the right track to making this work?

Thanks again.
Trope
 
I have no experience in code patching or even asm programming, I'm only planning to do in the future something like you are now doing. Nevertheless - some notes.
1. Your checkForPatch() function must have a parameter - value of address to checked code, because only the function including these lines can calculate exact address of that piece of code.
2. NOP-testing, I think, is not only mean to check for hacking - your critical lines could be patched by hacker using some JMP's as well. Check sum testing of whole critical snippet would be good idea, but I believe, such relocable referencies like "CALL Applicat.goodGuyMessage" are corrected by .exe loader directly before the execution.
3. Your "if(checkForPatch() == 1)" is exactly the same way hacker-sensitive like "if(theFlag == 5)". So better approach would be to include code of your correct JMP inctruction or some offset of your function pointers table into the password body - so without correct password there would be no information in your program to run correctly.
 
> 1. Your checkForPatch() function must have a parameter - value of address to checked code, because only the function including these lines can calculate exact address of that piece of code.

I'm wrong - if source text is unchanged, offset from beginning of the function to the piece with critical instructions should be constant.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top