Log in

View Full Version : Try to Create a Patcher


_ColdMind
January 13th, 2004, 04:00
I have tried to compare two files: the original and the patched one, character by character and store the offset and the patched code using the following C sequence, but it shows me strange things, not my patch:
Code:

FILE *f1,*f2;
f1=fopen(argv[1],"r";
f2=fopen(argv[2],"r";
int ch1, ch2, j=0;
unsigned long int i=0;
do {
ch1=fgetc(f1);
ch2=fgetc(f2);
if(ch1!=ch2) printf("\n %08X: %X", i, ch2);
i++;
if(i%25==0) {
printf("\n -- page %d -- more --",++j);
getch();
}
} while(ch2!=EOF);
printf("\n -- end --";
return;
}


Then I have triend to patch a file using the following C code, but this time I gived up and remember about woodmann... Would you like to help me ?

FoolFox
January 13th, 2004, 06:41
And what is the trouble ?

as far as I've seen by quickly look at the code, it should work
as intended....

what are the strange things you talk about ?

Regards
FoolFox

chlankboot
January 13th, 2004, 06:57
i think ur code is correct,
tip : try to debug it step by step within the ide
good luck

naides
January 13th, 2004, 09:15
Are the files open as binary or text mode?

_ColdMind
January 14th, 2004, 02:41
I get the same result in both text or binary. When it try to compare that two files the original and the craked one I see a lot of pages filled with zeros. Maybe Hiew (the hex-editor I have used to patch that file) recalculates the crc32 (cyclic redundancy checksum).

Do you say it must works.

ZaiRoN
January 14th, 2004, 04:48
Quote:
Do you say it must works.
I tried your snippet on both text and binary files and it works.
Don't know if the problem is related with the hex editor you have used (hiew in your case), try to use another one and retry...

TQN
January 14th, 2004, 23:10
Hi _ColdMind !
Base on your code, I revise, debug and rewrite it. The code works fine. I compiled with BCC 5.5.
Code:

// Compare.cpp
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void main(int argc, char *argv[])
{
if (argc != 3)
{
printf("Invalid command line.\n";
return;
}

FILE *f1 = fopen(argv[1], "rb";
if (NULL == f1)
{
printf("Could not open first file %s\n", argv[1]);
return;
}

FILE *f2 = fopen(argv[2], "rb";
if (NULL == f2)
{
printf("Could not open second file %s\n", argv[2]);
return;
}

int ch1, ch2, j = 0;
unsigned long int i = 0;

do {
ch1 = fgetc(f1);
ch2 = fgetc(f2);
if (ch1 != ch2)
{
printf("\n%08X:\t%02X\t%02X", i, ch1, ch2);
if (0 == (++j % 24))
{
printf("\n -- page %d -- more --", j / 25);
getch();
}
}
i++;
} while ((EOF != ch1) && (EOF != ch2));

fclose(f1);
fclose(f2);

printf("\n-- end --\n";
}

Hope you will test it.
Best regards!
TQN

elfz
January 15th, 2004, 10:14
Quote:
[Originally Posted by TQN]
} while ((EOF != ch1) && (EOF != ch2));


maybe I'm wrong, but shouldn't you use "while (!feof(f1) && !feof(f2))"
instead? If you're working with binary files, it's very likely that you'll encounter "EOF" (1ah ASCII, if i remember correctly) in the contents of the file, and the comparison will end there.

ZaiRoN
January 15th, 2004, 10:59
Hi elfz,
Quote:
but shouldn't you use "while (!feof(f1) && !feof(f2))"
You can use both; EOF is -1

_ColdMind
January 16th, 2004, 05:04
Thanks a lot TQN. Your code works.
Yes, both (!feof and !=EOF) can be used but I like EOF more.
There is a little problem: %X print short int I sould use %lX
---
The topic is about a patcher. I have used fseek to seek to the given offset and fputc to put the given opcode. File is patched but it runs like unpatched.

ZaiRoN
January 16th, 2004, 05:09
Quote:
I have used fseek to seek to the given offset and fputc to put the given opcode. File is patched but it runs like unpatched.
Can you post your code?

ZaiRoN

_ColdMind
January 16th, 2004, 05:37
This is the code
Code:

#include <stdio.h>

char *file="pstudio.exe";

int patch(long offset, int opcode);

main() {
patch(0x00439F9B,0x74);
patch(0x00439FA5,0x74);
patch(0x004830DC,0x84);
patch(0x0048AAFB,0x84);
patch(0x0048E0D5,0x85);
patch(0x00497D04,0x75);
patch(0x004BA952,0x75);
patch(0x004BA977,0x90);
return 0;
}

int patch(long offset, int opcode) {
FILE *f=fopen(file,"r+";
printf("%X %X", offset, opcode);
fseek(f,offset,SEEK_SET);
fputc(opcode,f);
return 0;
}

Maybe the prototype should be:
Code:

int patch(unsigned long offset, int opcode) ;

ZaiRoN
January 16th, 2004, 06:26
Hi _ColdMind,
Your error resides in this line: fseek(f,offset,SEEK_SET);
Code:
int fseek(
FILE *stream, ; Pointer to FILE structure.
long offset, ; Number of bytes from origin.
int origin ; Initial position.
);
The 'offset' parameter represents the number of bytes from origin (the classical definition of 'offset') and not the Virtual Address of the instruction to patch. You have to convert all the VA into offset and then pass them to your 'patch' function.

Another little thing: the file is opened every time you need to patch a byte but it's not closed, you should close the file using fclose function: fclose(FILE *);
You can open the file at the beginning of the main procedure, apply all the patch you need, and then close the file (at the end of the main procedure).


Quote:
Maybe the prototype should be...
No...

Best regards,
ZaiRoN

doug
January 17th, 2004, 11:53
you should also considering using some error checking code.
i.e: return values of the functions you called..

In most cases, that can help you pinpoint the location of your bug rapidely. and well, it's generally a good thing to do

_ColdMind
January 18th, 2004, 05:48
Hi all.
Thanks a lot for help. I am so inattendive sometimes. All the problemes were solved. I know that I must close every opened stream and handle errors but it was happened because I wrote the entire code on the flow at school once I have posted the message. The original source file on my home computer is great. I used a bidimensional array to store patch offset on the first line and the patch opcode on the second line and parse it in the main function, so this program is faster. I have discovered that the file offset is not the same thing as that address showed by my disassembler after I have posted. Thanks and forgive my absent-mindedness.