Modification of plant vs zombie with Java (Continued)
Previously used HxD Hex Editor The tool successfully modified the game archive, For specific steps, please refer to: https://blog.csdn.net/weixin_50669669/article/details/120984999, This article will use java Code replacement tool to achieve the same modification function.
1, Foreword
After the last game modification with HxD Hex Editor tool, the following problems were considered:
- To modify with HxD Hex Editor tool, you need to download the tool and have to perform hexadecimal calculation by yourself. It's really a little troublesome!
- Can we develop a modifier like that on the market (you can modify it after downloading) for everyone to use?
- The archived data of the game can be easily obtained and modified, so it can be inferred that the archives of many games can be obtained and modified. Is there any way to prevent this from happening?
Now we will discuss these problems one by one
Note: due to the lack of knowledge of this talent, it is impossible to achieve the desired problems at the current stage. This paper is only about its thinking and some personal views. When my ability is enough, I will solve and improve it.
2, Partial implementation process
1. Development environment
Java version: JDK1.8
Using tool: IntelliJ IDEA
2. Development ideas
-
Read data: because the data file of the game is stored in the local storage location is known;
C:\ProgramData\PopCap Games\PlantsVsZombies\userdata\user1.dat
So first read the data in user1.dat.
-
Modify data: according to previous attempts, you can get the desired results by modifying the data in the first row of user1.dat.
-
Write data: write the modified data back to user1.dat.
3. Involving knowledge
-
Use of IO stream (obtain and output the data to be changed)
Byte: (input) inputterm (output) outputstream
Characters: reader writer
In: read in the file
Out: write your own things into the file.
Reader: read things out;
Witter: write something in.
Byte stream (FileInputStream)
Byte input stream: read the file into memory for use. First read the file into memory from the disk, and then use it to load it. -
Binary conversion
Since the acquired data is hexadecimal data, and the user's input of the modified level is decimal, hexadecimal conversion is required
Refer to the following articles for the knowledge involved: IO Stream (read / write of file): https://blog.csdn.net/dkwjava/article/details/88858486 https://blog.csdn.net/qq_31360175/article/details/49407005 https://baike.baidu.com/item/IO/5918 https://baijiahao.baidu.com/s?id=1667654018904536818&wfr=spider&for=pc
4. Partial core implementation
- Define the global variable userIndex to store the data (array) read out under the. dat file
- Define the global variable fileName and declare the local path where. dat is located.
static ArrayList<Integer> userIndex=new ArrayList<>(); static String fileName="C:\\ProgramData\\PopCap Games\\PlantsVsZombies\\userdata\\user1.dat";
- Read the data of the first row in user1.dat
// Read data from binary files (hexadecimal data is automatically converted to decimal when output to the console) public static void readData(){ try { FileInputStream fis= new FileInputStream(fileName); BufferedInputStream br = new BufferedInputStream(fis); int record = -1; while((record = br.read()) != -1) { userIndex.add(record); } System.out.println("Read the first line of data display from the document(decimal system): "); for(int i=0; i<16; i++){ System.out.print(userIndex.get(i) + " "); } System.out.println(); } catch(Exception e) { System.out.print(e.toString()); } }
-
If else loop statement is used to modify data
Modification of game levels
if (type.equals("1")){ System.out.println("Please enter the level you want to change:(Cases; two-6)"); Scanner input=new Scanner(System.in); String level=input.nextLine(); int firstLevel=Integer.valueOf(level.substring(0,1)); int lastLevel=Integer.valueOf(level.substring(2,3)); if (firstLevel < 1 || firstLevel > 5 || lastLevel < 1 || lastLevel > 10){ System.out.println("Error"); System.out.println("There is no such level, please re-enter"); }else { //The number of jumping levels is p-q, and the number of levels is: (p-1)*10+q int addLevel = (firstLevel - 1) * 10 + lastLevel; //Modify data: the number of levels is at 04 in the first row, that is, the subscript in the array is 4 userIndex.set(4, addLevel); } }
Gold coin modification
In the. dat file, the number of gold coins consists of 08, 09, 0A and 0b, which are storage bits and contain 8 hexadecimal bits. Therefore, it is necessary to supplement the insufficient bits in front. This idea uses a for loop, and the number of loops is (len gt h of 8-hexadecimal number). For example, "989680 - > 00989680". After completion, replace the value of 08 - > 0b with two digits in the order of low - > high. For example, "80,96,98,00" replaces the values of "08,09,0a,0b" respectively.
else if (type.equals("2")){ System.out.println("Please enter the number of gold coins you want to change:"); Scanner input=new Scanner(System.in); String money=input.nextLine(); //Money to add int needMoney=Integer.valueOf(money)/10; String HexMoney=Integer.toHexString(needMoney); //Fill 0 to 8 digits in front of the hexadecimal number (the number of gold coins is from 08, 09, 0a and 0b are storage bits) String zero=new String(); for (int i=0;i<8-HexMoney.length();i++){ zero+="0"; } HexMoney=zero+HexMoney;//Complete hexadecimal //The last two digits, corresponding to the 08 position of the first line, are replaced int data08=Integer.valueOf(HexMoney.substring(HexMoney.length()-2)); userIndex.set(8, Integer.parseInt(String.valueOf(data08),16)); //The penultimate 3 and 4 bits correspond to the 09 position of the first line and are replaced int data09=Integer.valueOf(HexMoney.substring(4,6)); userIndex.set(9, Integer.parseInt(String.valueOf(data09),16)); //The 3rd and 4th bits of the positive number correspond to the first row 0a position and are replaced int data0a=Integer.valueOf(HexMoney.substring(2,4)); userIndex.set(10, Integer.parseInt(String.valueOf(data0a),16)); //The first and second bits of the positive number correspond to the first row 0a position and are replaced int data0b=Integer.valueOf(HexMoney.substring(0,2)); userIndex.set(11, Integer.parseInt(String.valueOf(data0b),16)); }else if(type.equals("3")){ //Modify data: the number of levels is in the first row 0c position, that is, the subscript in the array is 12 userIndex.set(12,1); }
Unlock all modes
Change the number of 0c bits to 01
else if(type.equals("3")){ //Modify data: the number of levels is in the first row 0c position, that is, the subscript in the array is 12 userIndex.set(12,1); }
-
Write the modified data to user1.dat
// Writes the array to a binary file public static void writeData() throws IOException { FileOutputStream fileWriter=new FileOutputStream(fileName,false); for (int singleData:userIndex) { fileWriter.write(singleData); } //write file fileWriter.close(); }
3, Code defect
-
If the infinite loop function is not realized, that is, if you do not click to exit the modification, you can always modify through the modification interface
-
Failed to realize the function of gold coins reaching the upper limit (it can be known from HxD Hex Editor that there is an upper limit for gold coins in the game)
-
Modifications that fail to achieve other functions, such as solar value, plant attack power, etc
-
Failed to implement the function encapsulation, which is troublesome to modify
-
It cannot be made into software, and Java environment is required for modification
Recommend some good article links (some defective functions have been implemented) CSDN Practical training - adopt Java Modify game Archive: https://blog.csdn.net/qq_48455576/article/details/121002191 Modify plant vs zombie game Archive( Java Implementation version): https://blog.csdn.net/m0_50207094/article/details/121006091 Java Memory modifier for plug-in development(similar CE): https://blog.csdn.net/qq969422014/article/details/53544071
4, Summary and personal views
-
Risk control and penetration
It can be seen that through the above few simple steps, the cracking and tampering of the game is over. For the cracker, it's only a matter of minutes, but for the game developer, it's a tragedy that how many overtime and efforts have been wasted. It is not easy to develop and provide application security, so we need to take precautions. Writing code rules, vulnerability detection or using third-party encryption protection are all ways to avoid cracking.
-
summary
Due to my limited ability, many contents of this article are created for reference and sorting out other people's articles. In the future, when my knowledge reserve reaches a certain level, I will improve the project. Please understand!