PDA

View Full Version : پچ کردن مقدار آدرس آفست یک فایل



ASM6502
دوشنبه 20 اردیبهشت 1395, 18:56 عصر
میخوام یه فایل test.bin رو باز بکنم و چند جاش مقادیرش رو عوض بکنم.
راه دستیش استفاده از یه هگزا ادیتور هست (مثل HxD)
ولی میخوام واسه این کار یه برنامه بنویسم که اتوماتیک مقادیر مورد نظرم رو روی فایل بنویسه.
توی اینترنت جستجو کردم ولی نتونستم دقیقا اون چیزی که میخواستم رو پیدا بکنم.
ولی چند تا مثال مرتبط پیدا کردم که تونستم با ترکیبشون به چیزی که میخوام برسم.
برنامه ظاهرا خوب کار میکنه.
ولی اگه میشه یه نفر یه نگاهی بندازه ببینه مورد ناشیانه ای توی برنامه هست یا نه که بعدا باعث باگ نشه.
مثلا اینکه آیا نیاز هست که حی فایل رو باز و بسته بکنم؟
یا اون قسمت بک آپ مشکلی ایجاد نمیکنه؟
مرسی

ضمنا مراحل اجرای برنامه هم به این صورت هست :
قسمت اصلی برنامه داخل یه تابع هست.
تابع با سه تا آرگومان فراخوانی میشه : نام فایلی که میخوام پچ بشه / آدرس آفستی که میخوام پچ بشه / مقدار جدیدی که میخوام داخل اون آدرس آفست نوشته بشه
با فراخوانی تابع :
اول : سایز فایل پیدا میشه
دوم : تک تک بایت های فایل به داخل آرایه Buffer لود میشه
سوم : از فایل اصلی یه بک آپ ایجاد میشه
چهارم : با توجه به آرگومان های تابع مقدار مورد نظر روی آرایه بافر نوشته میشه
پنجم : تک تک بایت های آرایه بافر به داخل فایل نوشته میشه



# include <iostream>
using namespace std;

void patch_file(std::string filename,int offset, int value);

void main ()
{
// File name, Offset, Value to patch
patch_file("test.bin", 0x0F, 0xFF);
}

void patch_file(std::string filename,int offset, int value)
{
// File Size
FILE *file_size = NULL;
file_size = fopen(filename.c_str(),"rb");
fseek(file_size,0,SEEK_END);
int size = ftell(file_size);
fclose (file_size);

// File to Buffer
FILE *read_file = NULL;
read_file = fopen(filename.c_str(),"rb");
unsigned char *buffer = new unsigned char[size];
fread(buffer,1,size,read_file);
fclose (read_file);

// Backup from File
FILE *backup_file = NULL;
char backup[20];
strcpy(backup, filename.c_str());
strcat (backup, ".backup");
backup_file = fopen(backup,"wb");
fwrite(buffer,1,size,backup_file);
fclose (backup_file);

// Patch value to buffer
buffer [offset] = value;

// Buffer to File
FILE *write_file = NULL;
write_file = fopen(filename.c_str(),"wb");
fwrite(buffer,1,size,write_file);
fclose (write_file);
}

vahid-p
پنج شنبه 23 اردیبهشت 1395, 16:16 عصر
شما خیلی از شرایط رو چک نکردید آیا موفقیت آمیز بوده یا خیر. یکی از شرایط پایداری برنامه چک کردن عملیات های ناموفق است.
دوم اینکه اگر منطق برنامه درست باشه نیازی به بک آپ گرفتن کل فایل و انتقال کل فایل به RAM نیست، بلکه کافیه یک فایل Log درست کنید و هر تغییراتی رو در اون ذخیره کنید.
مثلا:


FileName: text.bin, FilePath: C:\x\x, Size:67KB, Edited 7849 byte from 0xEA to 0xFF, Successfully

اگر بتونی یه MD5 هم براش حساب کنی که چه بهتر. مثلا MD5 قبل از عملیات تغییر، MD5 بعد از عملیات تغییر. خب اگر پس از عمل معکوس MD5 قبلی حاصل شد، یعنی به احتمال زیاد فایلت آسیب ندیده.
شما چندین و چند بار فایل رو باز، بسته کردید که این کار درستی به نظر نمیرسه.
راستی در تابع fseek طبق لینک http://www.cplusplus.com/reference/cstdio/fseek/ بهتره از SEEK_END استفاده نکنید:

* Library implementations are allowed to not meaningfully support SEEK_END (therefore, code using it has no real standard portability).
همچنین برای کپی کردن یک فایل روش های مختلفی وجود داره که شاید ریختن کل فایل تو رم و تغییر یک کاراکتر و نوشتن دوباره کل فایل در اون قسمت جالب به نظر نیاد. در صورتی که میتونی از seekg و seekp استفاده کنی.
البته من خیلی وقته با C++‎‎‎‎‎‎‎‎‎‎‎‎ کد نزدم ولی این تغییراتی بود که به نظرم ضروریه.

fstream به جای FILE به نظر میاد بد نباشه :لبخند:

ASM6502
پنج شنبه 23 اردیبهشت 1395, 19:21 عصر
مرسی که وقت گذاشتی و بررسی کردی
برنامه پست اول یه ایراد منطقی داره
تمام عملیات رو داخل یه دونه تابع تعریف کردم که این درست نیست
با یه بار فراخوانی تابع برنامه درست کار میکنه ولی اگه چندین بار تابع رو فراخوانی بکنم عمل بک آپ گیری درست انجام نمیشه
هر بار که تابع رو فراخوانی میکنم تا یه آدرس آفست رو تغییر بدم برنامه یه بک آپ جدید ایجاد میکنه که با فراخوانی های پی در پی باعث میشه که حی عمل بک آپ گیری انجام بشه و در نهایت بک آپ ایجاد شده متفاوت از فایل اصلی میشه
برنامه رو به این صورت اصلاح کردم که به درستی کار میکنه و مشکلی نداره :

# include <iostream>
# include <conio.h>

using namespace std;

void backup_file(std::string filename);
void patch_file(std::string filename,long int offset, int value);

void main ()
{
cout << "Random crash fix for Romance of the Three Kingdoms XI [PC][Eng][V1.0]" << endl;
cout << "\t Patch Version : 1.0" << endl;
cout << "\t Rlease date : 2016/05/09" << endl;
cout << "\t Created By Farid" << endl;
cout << "\t krauser35@yahoo.com" << endl;
cout << endl;
cout << "This patch fix the annoying random crash by removing the following officers :" << endl;
cout << "\t offset : 0x18B5F : Deng Ai" << endl;
cout << "\t offset : 0x18DBF : Deng Xian" << endl;
cout << "\t offset : 0x18E57 : Deng Zhi" << endl;
cout << "\t offset : 0x19317 : Deng Zhong" << endl;
cout << "\t offset : 0x1960F : Deng Mao" << endl;
cout << "\t offset : 0x197D7 : Ning Sui" << endl;
cout << endl;
cout << "Note : You have to copy the patch to the following location and run it :" << endl;
cout << "C:\\Program Files\\Koei\\RTKXI\\Media\\scenario" << endl;
cout << endl;
cout << "Do you want to apply the patch? [yes] [no] : " ;
char check[3];
cin >> check;

int ok1, ok2;
ok1 = strcmp (check,"yes");
ok2 = strcmp (check,"YES");

if ( (ok1!=0) && (ok2!=0) )
exit (0);

// Backup from files
backup_file ("Scen000.s11");
backup_file ("SCEN001.S11");
backup_file ("SCEN002.S11");
backup_file ("SCEN003.S11");
backup_file ("SCEN004.S11");
backup_file ("SCEN005.S11");
backup_file ("SCEN006.S11");
backup_file ("SCEN007.S11");

cout << endl;
cout << "Created backup from the following files :" << endl;
cout << "\t Scen000.s11" << endl;
cout << "\t SCEN001.S11" << endl;
cout << "\t SCEN002.S11" << endl;
cout << "\t SCEN003.S11" << endl;
cout << "\t SCEN004.S11" << endl;
cout << "\t SCEN005.S11" << endl;
cout << "\t SCEN006.S11" << endl;
cout << "\t SCEN007.S11" << endl;

// File name, Offset, Value to patch
patch_file("Scen000.s11", 0x18B5F, 0xFF); // Deng Ai
patch_file("Scen000.s11", 0x18DBF, 0xFF); // Deng Xian
patch_file("Scen000.s11", 0x18E57, 0xFF); // Deng Zhi
patch_file("Scen000.s11", 0x19317, 0xFF); // Deng Zhong
patch_file("Scen000.s11", 0x1960F, 0xFF); // Deng Mao
patch_file("Scen000.s11", 0x197D7, 0xFF); // Ning Sui

patch_file("Scen001.S11", 0x18B5F, 0xFF); // Deng Ai
patch_file("Scen001.S11", 0x18DBF, 0xFF); // Deng Xian
patch_file("Scen001.S11", 0x18E57, 0xFF); // Deng Zhi
patch_file("Scen001.S11", 0x19317, 0xFF); // Deng Zhong
patch_file("Scen001.S11", 0x1960F, 0xFF); // Deng Mao
patch_file("Scen001.S11", 0x197D7, 0xFF); // Ning Sui

patch_file("Scen002.S11", 0x18B5F, 0xFF); // Deng Ai
patch_file("Scen002.S11", 0x18DBF, 0xFF); // Deng Xian
patch_file("Scen002.S11", 0x18E57, 0xFF); // Deng Zhi
patch_file("Scen002.S11", 0x19317, 0xFF); // Deng Zhong
patch_file("Scen002.S11", 0x1960F, 0xFF); // Deng Mao
patch_file("Scen002.S11", 0x197D7, 0xFF); // Ning Sui

patch_file("Scen003.S11", 0x18B5F, 0xFF); // Deng Ai
patch_file("Scen003.S11", 0x18DBF, 0xFF); // Deng Xian
patch_file("Scen003.S11", 0x18E57, 0xFF); // Deng Zhi
patch_file("Scen003.S11", 0x19317, 0xFF); // Deng Zhong
patch_file("Scen003.S11", 0x1960F, 0xFF); // Deng Mao
patch_file("Scen003.S11", 0x197D7, 0xFF); // Ning Sui

patch_file("Scen004.S11", 0x18B5F, 0xFF); // Deng Ai
patch_file("Scen004.S11", 0x18DBF, 0xFF); // Deng Xian
patch_file("Scen004.S11", 0x18E57, 0xFF); // Deng Zhi
patch_file("Scen004.S11", 0x19317, 0xFF); // Deng Zhong
patch_file("Scen004.S11", 0x1960F, 0xFF); // Deng Mao
patch_file("Scen004.S11", 0x197D7, 0xFF); // Ning Sui

patch_file("Scen005.S11", 0x18B5F, 0xFF); // Deng Ai
patch_file("Scen005.S11", 0x18DBF, 0xFF); // Deng Xian
patch_file("Scen005.S11", 0x18E57, 0xFF); // Deng Zhi
patch_file("Scen005.S11", 0x19317, 0xFF); // Deng Zhong
patch_file("Scen005.S11", 0x1960F, 0xFF); // Deng Mao
patch_file("Scen005.S11", 0x197D7, 0xFF); // Ning Sui

patch_file("Scen006.S11", 0x18B5F, 0xFF); // Deng Ai
patch_file("Scen006.S11", 0x18DBF, 0xFF); // Deng Xian
patch_file("Scen006.S11", 0x18E57, 0xFF); // Deng Zhi
patch_file("Scen006.S11", 0x19317, 0xFF); // Deng Zhong
patch_file("Scen006.S11", 0x1960F, 0xFF); // Deng Mao
patch_file("Scen006.S11", 0x197D7, 0xFF); // Ning Sui

patch_file("SCEN007.S11", 0x18B5F, 0xFF); // Deng Ai
patch_file("SCEN007.S11", 0x18DBF, 0xFF); // Deng Xian
patch_file("SCEN007.S11", 0x18E57, 0xFF); // Deng Zhi
patch_file("SCEN007.S11", 0x19317, 0xFF); // Deng Zhong
patch_file("SCEN007.S11", 0x1960F, 0xFF); // Deng Mao
patch_file("SCEN007.S11", 0x197D7, 0xFF); // Ning Sui

cout << endl;
cout << "Patch applied successfully!" << endl;
cout << endl;
cout << "Press any key to exit...";
getch ();
}

void backup_file(std::string filename)
{
// File Size
FILE *file_size = NULL;
file_size = fopen(filename.c_str(),"rb");
fseek(file_size,0,SEEK_END);
int size = ftell(file_size);
fclose (file_size);

// File to Buffer
FILE *read_file = NULL;
read_file = fopen(filename.c_str(),"rb");
unsigned char *buffer = new unsigned char[size];
fread(buffer,1,size,read_file);
fclose (read_file);

// Backup from File
FILE *backup_file = NULL;
char backup[20];
strcpy(backup, filename.c_str());
strcat (backup, ".backup");
backup_file = fopen(backup,"wb");
fwrite(buffer,1,size,backup_file);
fclose (backup_file);
}

void patch_file(std::string filename,long int offset, int value)
{
// File Size
FILE *file_size = NULL;
file_size = fopen(filename.c_str(),"rb");
fseek(file_size,0,SEEK_END);
int size = ftell(file_size);
fclose (file_size);

// File to Buffer
FILE *read_file = NULL;
read_file = fopen(filename.c_str(),"rb");
unsigned char *buffer = new unsigned char[size];
fread(buffer,1,size,read_file);
fclose (read_file);

// Patch value to buffer
buffer [offset] = value;

// Buffer to File
FILE *write_file = NULL;
write_file = fopen(filename.c_str(),"wb");
fwrite(buffer,1,size,write_file);
fclose (write_file);
}