Red de conocimiento informático - Conocimiento del nombre de dominio - Cómo hacer de Plants vs. Zombies un modificador que pueda crear plantas

Cómo hacer de Plants vs. Zombies un modificador que pueda crear plantas

Producción de modificadores de juegos: introducción al hacking

Herramientas: SoftICE, Kingsoft Ranger 2002, VC++7.0, PE Viewer, SPY++

Plataforma de prueba: Window2000 Professional SP2

Antes que nada, déjame presentarte las herramientas que se utilizarán:

1 SoftICE (no hace falta decir más, creo que deberías poder usarlo) <. /p>

2. Kingsoft Ranger 2002 (también deberías poder usarlo)

3. al menos una herramienta de programación)

4. Visor PE (puedes encontrar uno a tu antojo, no importa si no tienes uno, te enseñaré a usar SoftICE para verlo)

5. SPY++ (una herramienta en VC para ver información del programa, puedes usarla con otros, como Delphi y WinSight32 de C++Builder)

A continuación, los conocimientos que debes conocer:

1. Conceptos básicos del ensamblaje

2. Algunos conceptos básicos de programación. Al menos deberías comprender las pocas funciones API que presenté.

3. no conoces los conceptos básicos de la estructura de archivos PE, te los explicaré

Tienes todos los puntos anteriores. Si es así, podemos comenzar.

Déjame presentarte lo que quiero enseñarte. Creo que todos han jugado juegos de PC, por lo que deben haber usado algunos modificadores de juego especiales. Los juegos clásicos como Diablo, Red Alert y Monopoly tienen sus propios modificadores especiales. Nota, no me refiero a la herramienta de modificación general para clases. .

¿Has probado a usar Kingsoft Ranger para modificar el dinero en Red Alert 2? En todo caso, debes saber que debes cambiarlo cada vez que juegues, porque este juego asigna memoria dinámicamente y cambiará cada vez que reinicies. Entonces elegirías conectarte y descargar un modificador especial. ¿Alguna vez has pensado en crear uno tú mismo? ¿Lo has pensado? Entonces ¿por qué no lo haces? ¿Qué no lo hará? Eso es fácil de hacer. Lo sabrás después de leer este tutorial: D Sin más preámbulos, déjame explicarte el principio.

Algunos amigos que modifican juegos con frecuencia sabrán que no importa si la dirección de memoria de los "elementos" del juego es dinámica o no, la distancia entre los elementos permanece sin cambios. Tomé "Chu Liuxiang" "Nuevo". Leyenda" como ejemplo, primero utilicé Jinshan Ranger para encontrar la dirección de memoria del valor de fuerza interna, y el resultado encontrado fue: 79F695C, y luego la dirección del elemento "Medicina Jinchuang" fue: 328D1DC. Ahora resté 328D1DC de 79F695C, y obtuve: 4769780, este número es el valor de compensación entre el valor de la fuerza interna y la medicina dorada, ¿no lo entiendes? Entonces mira, aún no he terminado. Ahora ejecuta el juego nuevamente y busca la dirección del valor de fuerza interna, y obtén: 798695C. Luego busca a Jin Chuangyao y obtén la dirección: 321D1DC. ​han cambiado, pero usando ¿Cuál es el resultado de restar la dirección de Jin Chuang Yao de la dirección de su valor de fuerza interna? Así es, sigue siendo 4769780. Es decir, no importa cuán grandes sean las direcciones de memoria de estos dos valores, la distancia entre ellos nunca cambiará, no solo en este juego, sino también en los juegos en general. No lo he visto :D

Lo que dijimos arriba lleva a una conclusión, es decir, siempre que obtengamos cualquiera de estas dos direcciones, podemos obtener la otra, siempre que lo sepas. el desplazamiento entre ellos es ¿Cuántos?

El primer paso que tenemos que hacer es obtener esta dirección, pero la dirección en la memoria cambia dinámicamente, por lo que es inútil obtenerla. Aquí te enseñaré a hacerla estática para que así sea. ¡Nunca cambies! Continuaré tomando "La nueva leyenda de Chu Liuxiang" como ejemplo. Si tienes este juego, hazlo conmigo. Si no lo tienes, no importa, siempre que los entiendas. pasos.

¡comenzar!

Primero ingrese al juego, busque la dirección del valor interno y obtenga: 798695C (no sé por qué el upstream no cambia la dirección de la memoria cada vez que se reinicia), presione Ctrl+ D para abrir SoftICE, y emitir el comando: BPM 798695C W (interrumpir al escribir esta dirección), regresar al juego, abrir el panel de propiedades del personaje, el juego se interrumpe, verás este comando en SofitICE:

0047EB17 MOV EAX [EDX+ 000003F4] Emita el comando: D EDX+3F4 y verá el valor de la fuerza interna

0047EB1D PUSH EAX

…………………… ……………………

………………………………

De lo anterior se puede ver que la instrucción en 0047EB17 envía el puntero de el valor de fuerza interna al registro EAX. Este es un método de direccionamiento típico. Imagínese. Ahora, hemos llegado a la dirección base en EDX, por lo que siempre que usemos EDX+3F4, podemos obtener fácilmente la dirección del valor de fuerza interna. 000003F4 es una constante, no cambiará, solo cambia la dirección en EDX, por lo que siempre que haya una manera de obtener el valor en EDX, todo será fácil. Si aún no lo entiendes, léelo de nuevo. Lo que debes hacer ahora es cómo obtener este valor. Te enseñaré cómo hacerlo a continuación:

Mi método consiste en diseñar un fragmento de código para almacenar el valor en EDX en una dirección y. luego ejecuta este código. Regresa a las instrucciones originales del juego y continúa ejecutando, ¿qué? ¿Tecnología de parches? SMC? Digas lo que digas, siempre que se ejecute normalmente, todo estará bien: D

Operación real:

Primero, busca un espacio en blanco en el programa para almacenar el código que diseñamos. Es muy simple. Cualquiera que conozca alguna estructura de archivos PE sabrá que generalmente hay un área de búfer al final del segmento de datos (segmento de datos) del archivo EXE. Por supuesto, podemos escribir cualquier cosa en esta área. También puedes usar "90 Dafa" "Encuentra un área en blanco, pero aún así te recomiendo que uses el método que te enseñé". Como mencioné anteriormente, si no tienes una herramienta de visualización de archivos PE, puedo enseñarte a usar SoftICE para verlos, y es muy simple. Solo requiere un comando: MAP32 “nombre del módulo”. Yo lo hago y lo sabrás.

Ctrl+D llama a SoftICE y luego emite el comando: MAP32 CrhChs En este momento deberías ver la información sobre cada segmento del EXE. A lo que debemos prestar atención es al segmento .data. Dado que estamos buscando el segmento de datos al final de El segmento .rsrc comienza en 00507000, lo que significa que un byte hacia arriba desde 00507000 es el final del segmento de datos, elegí comenzar a escribir código desde 00506950. Después de hablar por un. Mucho tiempo, ¿cómo es nuestro código? ¿Paño de lana? ¿Cómo se ve la instrucción modificada? No te preocupes, echa un vistazo a continuación:

Modifica el código después de 0047EB17:

0047EB17 JMP 00506950 //Salte a nuestro código para ejecutar

0047EB1C NOP // Dado que la longitud original de esta instrucción es de 6 bytes y la longitud modificada es de 5 bytes, se completa con una instrucción vacía

0047EB1D PUSH EAX

//We Code :

00506950 MOV DWORD PTR EAX, [EDX+00003F4] //Restaurar nuestras instrucciones destruidas

00506956 MOV DWORD PTR [00506961],EDX //Guardar EDX como Ir a 00506961

0050695C JMP 0047EB1D //Volver a la instrucción original para ejecutar

Escribe el código anterior usando el comando A de SoftICE, ¡OK!

Ahora probemos el efecto de ejecución. Ahora use Kingsoft Ranger para buscar la dirección de la fuerza interna. Eso es todo. Si no cambia, ¿todavía tenemos que esforzarnos tanto? Escribe esta dirección y regresa al juego. Ctrl+D llama a SoftICE y emite el comando D *[00506961]+000003F4 ¿Qué ves en la ventana de datos? Jaja, sí, vi la dirección que acabas de memorizar. El valor dentro es exactamente el valor de la fuerza interna. Intenta cambiarlo y regresa al juego. Jaja, el valor de la fuerza interna ha cambiado, cierto: D

<. p> En este punto, el 90% de nuestro trabajo se ha completado, pero no estés demasiado contento. El próximo 10% llevará mucho más tiempo que el primer 90%, porque tenemos que usar programación para lograr todo esto, porque tú. No puedo hacerlo cada vez. ¡Hazlo de nuevo como lo acabas de hacer!

Ahora déjame hablar sobre los pasos de programación:

Primero usa la función FindWindow para obtener el identificador de la ventana, luego usa la función GetWindowThreadID para obtener el ID del proceso desde el identificador de la ventana. y luego use OpenProcess para obtener la ID del proceso. Permisos de lectura y escritura, y finalmente use WriteProcessMemory y ReadProcessMemory para leer y escribir en la memoria, y luego. . . .

Jaja, tu modificador está listo :D

El siguiente es un fragmento del programa fuente del modificador que copié antes. La primera parte es escribir dinámicamente el código en este momento, y la segunda parte es leer y. modifíquelo. Valores de fuerza interna, ya que no tengo tiempo para organizarlos y probarlos, no puedo garantizar que no haya errores. Si encuentra algo que falta, puede dejarme un mensaje en QQ o escribirme el código. es el siguiente:

Algunos puntos Tenga en cuenta:

1 Al escribir código de máquina, escriba byte por byte

2. código primero y luego modifica las instrucciones del código del juego (el código a continuación no hace esto porque no lo afecta, pero debes prestar atención a este problema)

#define MY_CODE5 0x00

#define MY_CODE6 0x90

/ /00506950

#define MY2_CODE1 0x8B

#define MY2_CODE2 0x82 //Esta parte es la definición constante de el código de máquina a escribir

#define MY2_CODE3 0xF4

#define MY2_CODE4 0x03

#define MY2_CODE5 0x00

#define MY2_CODE6 0x00

#define MY3_CODE1 0x89

#define MY3_CODE2 0x15

#define MY3_CODE3 0x61

#define MY3_CODE4 0x69

#define MY3_CODE5 0x50

#define MY3_CODE6 0x00

p>

#define MY4_CODE1 0xE9

#define MY4_CODE2 0xBC

#define MY4_CODE3 0x81

#define MY4_CODE4 0xF7

# define MY4_CODE5 0xFF

//------------------ ----------------------- --------------------------- ------------//

DWORD A1 =MI_CÓDIGO1;

DWORD A2 =MI_CÓDIGO2

DWORD A3 =MI_CÓDIGO3;

DWORD A4 =MY_CODE4;

DWORD A5 =MY_CODE5 ;

DWORD A6 =MY_CODE6

DWORD B1 =MY2_CODE1; p>

DWORD B2 =MY2_CODE2;

DWORD B3 =MY2_CODE3; / /Esta parte es la definición de la variable

DWORD B4 =MY2_CODE4

DWORD B5 =MY2_CODE5;

DWORD B6 =MY2_CODE6;

DWORD C1 =MY3_CODE1

DWORD C2 =MY3_CODE2; C3 =MY3_CODE3;

DWORD C4 =MY3_CODE4;

DWORD C5 =MY3_CODE5;

DWORD C6 =MY3_CODE6

DWORD D1; MY4_CODE1;

DWORD D2 =MY4_CODE2

<

p>DWORD D3 =MY4_CODE3;

DWORD D4 =MY4_CODE4

DWORD D5 =MY4_CODE5

//----------; -------------------------------------------------- --------------//

HWND hWnd =::FindWindow("CRHClass",NULL //Obtener el identificador de la ventana

if (hWnd ==FALSE)

MessageBox("¡El juego no se está ejecutando!");

else

{

GetWindowThreadProcessId; (hWnd, &hProcId); // Obtener el ID del proceso desde el identificador de la ventana

HANDLE nOK =OpenProcess(PROCESS_ALL_ACCESS|PROCESS_TERMINATE|PROCESS_VM_OPERATION|PROCESS_VM_READ|

PROCESS_VM_WRITE,FALSE,hProcId); //Abre el proceso y obtén lectura y permiso

if(nOK ==NULL)

MessageBox("Error al abrir el proceso"); p>

{

//0047EB17

WriteProcessMemory(no OK,(LPVOID)0x0047EB17,&A1,1,NULL);

WriteProcessMemory(no OK, (LPVOID)0x0047EB18, &A2,1,NULL);

WriteProcessMemory(no OK,(LPVOID)0x0047EB19,&A3,1,NULL

WriteProcessMemory(no OK,(LPVOID)0x0047EB1A); ,&A4,1, NULL);

WriteProcessMemory(no OK,(LPVOID)0x0047EB1B,&A5,1,NULL);

WriteProcessMemory(no OK,(LPVOID)0x0047EB1C,&A6,1); ,NULL); )0x00506951,&B2, 1,NULL);

WriteProcessMemory(no OK,(LPVOID)0x00506952,&B3,1,NULL

WriteProcessMemory(no OK,(LPVOID)0x00506953,&B4); ,1,NULL) ;

WriteProcessMemory(no OK,(LPVOID)0x00506954,&B5,1,NULL

WriteProcessMemory(no OK,(LPVOID)0x00506955,&B6,1,NULL); );

//Segunda oración

WriteProcessMemory(nOK,(LPVOID)0x00506956,&C1,1,NU

LL);

WriteProcessMemory(no OK,(LPVOID)0x00506957,&C2,1,NULL);

WriteProcessMemory(no OK,(LPVOID)0x00506958,&C3,1,NULL); /p>

WriteProcessMemory(no OK,(LPVOID)0x00506959,&C4,1,NULL

WriteProcessMemory(no OK,(LPVOID)0x0050695A,&C5,1,NULL); p>WriteProcessMemory(nOK,(LPVOID)0x0050695B,&C6,1,NULL);

//Última frase

WriteProcessMemory(nOK,(LPVOID)0x0050695C,&D1,1,NULL

WriteProcessMemory(no OK,(LPVOID)0x0050695D,&D2,1,NULL);

WriteProcessMemory(no OK,(LPVOID)0x0050695E,&D3,1,NULL); p>

p>

WriteProcessMemory(no OK,(LPVOID)0x0050695F,&D4,1,NULL

WriteProcessMemory(no OK,(LPVOID)0x00506960,&D5,1,NULL); /p>

CloseHandle(nOK); //Cerrar el identificador del proceso

}

}

}

// ////// ///////////////////////////////////////////// ///////// ////////////////////////////////////////// //////////// /////////////////////////////////////// /////////////// //////////////////////////////////// //////////

//Leer y modificar el valor de fuerza interna

DWORD hProcId

HWND hWnd =::FindWindow( "CRHClass",NULL);

if(hWnd = =FALSE)

MessageBox("No");

else

{

GetWindowThreadProcessId(hWnd,&hProcId);

HANDLE nOK =OpenProcess(PROCESS_ALL_ACCESS|PROCESS_TERMINATE|PROCESS_VM_OPERATION|PROCESS_VM_READ|

PROCESS_VM_WRITE,FALSE,hProcId); /p>

if(nOK ==NULL)

MessageBox("ProcNo!"

else

{

DWORD buf1;

Escritura DWORD

BOOL OK=ReadProcessMemory(nOK,(LPCVOID)0x00506961,(LPVOID)&buf1,4,NULL)

; //Leer la base que guardamos en EDX

if(OK ==TRUE)

{

write =buf1+0x000003F4 //Obtener el interno; force Dirección del valor

DWORD Written =0x00; //Valor a modificar

BOOL B =WriteProcessMemory(nOK,(LPVOID)write,&Writeed,1,NULL

if(B==FALSE)

MessageBox("WriteNo"

}

}

CloseHandle; ( no OK);

}

Ah, tengo las manos entumecidas mientras escribo. Eso es todo por hoy. No tengo mucho talento e inevitablemente cometeré algunas omisiones. Un consejo. Si no sé o no sé escribir, si te gusta usar VC, puedes comunicarte conmigo en QQ y puedo enseñarte cómo usar Delphi, C++Builder, Win32Asm. o VC para implementar las funciones anteriores.

(Si reimprime este artículo, ¡no cambie el contenido ni el autor!)

Autor: CrackYY

Correo electrónico: CoolYY@msn.com

OICQ: 20651482

En 2001, aprendí cosas buenas como IDA de Yunfeng. Lo vi resolviendo los recursos del juego de Caesar. Pensé que era divertido y comencé a resolver algunas cosas yo mismo. Esa vez, resolví algunos recursos del juego de una vez. Por supuesto, no eran muy complicados. Eran principalmente de Taiwán y Japón.

Más tarde, los publiqué en la página de inicio por un tiempo. Recuerde que había muchos amigos interesados, no he tenido tiempo de hablar de ello, así que hablemos de cómo hacerlo ahora :)

La herramienta es, por supuesto, IDA+SoftIce. Si desea escribir el programa de descompresión usted mismo, también necesita un editor familiar. Por supuesto que uso VC.

De hecho, descifrar recursos no es muy complicado. Existen aproximadamente tres métodos

<. p>1. Cracking duro

Al observar el archivo de destino y el código de desensamblado, analice la compresión de recursos o el formato cifrado, escriba un programa para leer y modificar el archivo y convertirlo a un formato que pueda reconocer. .

Esta es la forma más fácil de pensar al decodificar recursos usted mismo

Específico En otras palabras, significa utilizar algunas funciones específicas, como funciones relacionadas con archivos como fopen. y createFile, para determinar la función de solución de recursos del juego, y luego analizar desesperadamente el código ensamblador.

La mayoría de mis primeros recursos eran Así es como se descifra. Es mejor usar UEDIT para analizar el. Primero el archivo real. Algunos formatos son demasiado simples. Puedes simplemente mirar el tamaño del archivo.

Este método es el más complicado que he resuelto. Es la serie Magic Legend. Es similar a GIF, pero no es lo mismo. No estudié el algoritmo de compresión, por lo que no lo estudié en profundidad. Sin embargo, luego leí un artículo en Internet que decía que era un algoritmo de compresión muy común. se puede descomprimir con algunas herramientas de descompresión, ◎#¥%... Es realmente frustrante (pero afortunadamente, solo me tomó unas horas descomprimir ese juego

2, Dump

Una vez cargada la imagen, expórtela directamente desde la memoria

Este enfoque también es fácil de imaginar. La principal dificultad radica en el formato de los recursos en la memoria. Esta solución puede no ser adecuada para 3D. juegos Es más fácil después de todo, la representación de texturas se realiza mediante la tarjeta gráfica, no mediante software.

Aprendí que algunas personas desbloquearon los recursos de World of Warcraft de esta manera, enganchando algunas funciones de OpenGL.

p>

He decodificado algunos textos del juego (texto chino) como este, para juegos de carreras. Para obtener todo el texto del juego, dije específicamente que el juego fue borrado.

3. decodificación del juego Función de decodificación

Es similar al segundo método, pero al llamar activamente a la función, básicamente puedes desbloquear todos los recursos a la vez, sin la necesidad de borrar el juego

Por supuesto, no se te pide que llames al módulo de desempaquetado del juego, después de todo, muchos juegos no están en forma de dll

Solo puedes invadir el proceso del juego y encontrar un momento adecuado (generalmente cuando cargar otros archivos, interrumpir y saltar, primero después de terminar nuestro trabajo), llamar a la función interna para desbloquear todos los recursos

Resolví un juego usando este método. Hablando de eso, la tasa de compresión de recursos de ese. El juego es casi igual que rar

p>

Documento de requisitos

El algoritmo de compresión LZW es un método de compresión novedoso creado conjuntamente por Lemple-Ziv-Welch y que lleva su nombre. . Utiliza una compresión avanzada de tabla de cadenas, que coloca cada cadena que aparece por primera vez en una tabla de cadenas y usa un número para representar la cadena. El archivo comprimido solo almacena números, no cadenas, lo que hace que el archivo tenga una gran eficiencia de compresión. mejorado. Lo maravilloso es que esta tabla de cadenas se puede establecer correctamente ya sea durante la compresión o la descompresión. Una vez completada la compresión o la descompresión, esta tabla de cadenas se descarta.

1. Principio básico

Primero cree una tabla de cadenas, coloque cada cadena que aparece por primera vez en la tabla de cadenas y represéntela con un número. as Esta cadena está relacionada con su posición en la tabla de cadenas y este número se almacena en el archivo comprimido. Si esta cadena aparece nuevamente, se puede reemplazar por el número que la representa y este número se almacena en el archivo. Una vez completada la compresión, la tabla de cadenas se descarta. Por ejemplo, si la cadena "imprimir" está representada por 266 durante la compresión, siempre que vuelva a aparecer, estará representada por 266 y la cadena "imprimir" se almacenará en la tabla de cadenas cuando se encuentre el número 266. durante la decodificación, se puede recuperar de la tabla de cadenas. Se encuentra la cadena "imprimir" representada por 266. Durante la descompresión, la tabla de cadenas se puede regenerar en función de los datos comprimidos.

2. Método de implementación

A. Inicializar la tabla de cadenas

Al comprimir información, primero cree una tabla de cadenas para registrar cada primera aparición de la cadena. Una tabla de cadenas consta de al menos dos matrices de caracteres, una se llama matriz actual y la otra se llama matriz de prefijo, porque la longitud de cada cadena básica en el archivo suele ser 2 (pero la longitud real de la cadena que representa puede ser hasta a varios cientos o incluso miles), una cadena básica consta del carácter actual y del carácter anterior (también llamado prefijo). El primer carácter de la cadena se almacena en la matriz de prefijo y el último carácter de la cadena se almacena en la matriz actual. Sus ubicaciones de almacenamiento son las mismas. Por lo tanto, siempre que se determine un subíndice, la cadena básica que almacena puede ser la misma. ser determinado, por lo que en los datos Al comprimir, se utilizan subíndices en lugar de cadenas base. Generalmente, el tamaño de la tabla de cadenas es de 4096 bytes (es decir, 2 elevado a 12), lo que significa que se pueden almacenar un máximo de 4096 cadenas básicas en una tabla de cadenas. Durante la inicialización, la tabla de cadenas se inicializará según el número. de caracteres en el archivo. Los bytes en la posición inicial son todos números asignados. Por lo general, el contenido de la matriz actual es el número de serie (es decir, el subíndice) del elemento. , el elemento 15 es 14, hasta El subíndice es el número de caracteres más 2 elementos. Si el número de caracteres es 256, se inicializa en el byte 258 y el valor en este byte es 257. El número 256 representa el código de borrado y el número 257 representa el código de fin de archivo. Los siguientes bytes almacenan cada primera aparición de la cadena en el archivo. También es necesario inicializar la matriz de prefijo de concierto, en la que el valor de cada elemento es un número arbitrario, pero generalmente cada posición se establece en 1 y cada elemento en la posición inicial se inicializa en 0XFF. lo mismo que la matriz actual y los elementos posteriores. Luego, se debe almacenar cada primera aparición de la cadena. Si se aumenta la longitud de la tabla de cadenas, la eficiencia de la compresión se puede mejorar aún más, pero se reducirá la velocidad de decodificación.

B. Método de compresión

Al comprender el método de compresión, primero debe comprender algunos sustantivos, uno es flujo de caracteres, el otro es flujo de código, el tercero es código actual y el cuarto es el prefijo actual. El flujo de caracteres son los datos del archivo sin comprimir en el archivo fuente; el flujo de código son los datos del archivo comprimido escritos en el archivo después de la compresión; el personaje acaba de leer.

Cuando se comprime un archivo, independientemente del número de caracteres del archivo, el valor del color debe colocarse en el flujo de código en unidades de bytes, y cada byte representa un color. Aunque se desperdiciarán 4 o más bits al usar un byte para representar 16 colores, 4 colores y 2 colores en el archivo fuente (porque 4 bits en un byte pueden representar 16 colores), pero use bits libres LZW en bytes se puede reciclar durante la compresión. Al comprimir, primero lea el primer carácter del flujo de caracteres como prefijo actual y luego tome el segundo carácter como código actual. El prefijo actual y el código actual forman la primera cadena básica (por ejemplo, el prefijo actual es). A, y el código actual es B, la cadena es AB), busque la tabla de cadenas y definitivamente no se encontrará la misma cadena en este momento, luego escriba la cadena en la tabla de cadenas, escriba el prefijo actual en el prefijo matriz, escriba el código actual en la matriz actual y envíe el prefijo actual al flujo de código, coloque el código actual en el prefijo actual y luego lea el siguiente carácter, que es el código actual. En este momento, un nuevo básico. Se forma la cadena (si el código actual es C, entonces esta La cadena básica es BC), busque la tabla de cadenas, si existe dicha cadena, descarte el valor en el prefijo actual, use el código de posición (es decir, subíndice) de la cadena en la tabla de cadenas como prefijo actual y luego lea el siguiente carácter como El código actual forma una nueva cadena básica hasta que se comprime todo el archivo.

Se puede ver que durante la compresión, los valores en la matriz de prefijos son los caracteres en el flujo de código. Los códigos mayores que la cantidad de caracteres deben representar una cadena, y los códigos menores o iguales a la cantidad de caracteres son los caracteres. ellos mismos.

C. Borrar código

De hecho, al comprimir un archivo, a menudo es necesario inicializar la tabla de cadenas varias veces, a menudo el número de cadenas básicas que aparecen por primera vez. en el archivo excederá 4096. Durante el proceso de compresión, siempre que la longitud de la cadena exceda 4096, el prefijo actual y el código actual deben ingresarse en el flujo de código, se debe agregar un código de borrado al flujo de código, la cadena La tabla debe inicializarse y la compresión debe continuar de acuerdo con el método anterior.

D. Código final

Cuando se completa toda la compresión, se envía un código final de archivo al flujo de código. Su valor es el número de caracteres más 1. En un formato de 256 colores. archivo, el código final es El código es 257.

E. Reciclaje de espacio en bytes

Además de almacenar los datos en el flujo de código de salida del archivo en forma de paquetes de datos, todos los códigos se almacenan en unidades, lo que ahorra espacio de almacenamiento de manera efectiva. . Esto es como un archivo de color de 4 bits (16 colores). Cuando se almacena en bytes, solo se pueden usar 4 bits y los otros 4 bits se desperdician. Cuando se almacena en bits, cada byte puede almacenar dos códigos de color. De hecho, en el archivo se utiliza un método de almacenamiento de números variables. Se puede ver en el proceso de compresión que los valores de cada elemento en la matriz de prefijos de la tabla de cadenas son regulares en el archivo de 256 colores, página 258. -511 El rango del valor mediano del elemento es 0-510, que puede representarse mediante un número binario de 9 dígitos. El rango del valor mediano del elemento 512-1023 es 0-1022, que puede representarse exactamente. por un número binario de 10 dígitos El valor medio del elemento 1024-2047 es El rango es 0-2046, que está exactamente representado por un número binario de 11 bits El rango del valor en el elemento 2048-4095 es 0. -4094, que está representado exactamente por un número binario de 12 bits. Cuando se utilizan dígitos variables para almacenar códigos, el número básico de dígitos es el número de caracteres en el archivo más 1. A medida que aumenta el número de códigos, el número de dígitos también aumenta hasta que el número de dígitos excede 12 (en este momento el número de caracteres en la tabla de cadenas El número de cadenas es exactamente 2 elevado a 12, es decir, 4096). El método básico es: cada vez que se agrega un carácter al flujo de código, es necesario determinar si la posición (es decir, el subíndice) de la cadena en la tabla de cadenas excede 2 elevado a la potencia del número actual de dígitos. excede, el número de dígitos aumenta en 1. Por ejemplo, en un archivo de 4 bits, el código al principio se almacena en 5 bits. Los 5 bits inferiores del primer byte son el primer código, los tres bits superiores son los 3 bits inferiores del segundo código. Los 3 bits inferiores del segundo byte se colocan en los 2 bits superiores del segundo código, y así sucesivamente. Para un archivo de 8 bits (256 colores), el número básico de bits es 9 y se debe colocar un código en un mínimo de dos bytes.

F. Rango de compresión

El siguiente es un ejemplo de codificación de archivos. Si presta atención, encontrará que este es un método de codificación maravilloso y por qué no existe la tabla de cadenas. Ya no es necesario después de que se completa la compresión. Además, la tabla de cadenas se puede volver a crear en función de la información del flujo de código durante la decodificación.

Cadena: 1,2,1,1,1,1,2,3,4,1,2,3,4,5,9,…

Código actual: 2,1,1,1,1,2,3,4,1,2,3,4,5,9,…

Prefijo actual: 1,2,1,1,260,1,258, 3 ,4,1,258,262,4,5,…

Matriz actual: 2,1,1, 1, 3,4,1, 4,5,9,…

Subíndice de matriz : 258,259,260,261,262,263,264,265,266,267,…

Flujo de código: 1,2,1,260,258,3,4,262,4,5,…

3. /p>

Al seleccionar, seleccione los datos del 1 al 3. Si selecciona otros datos, se producirá un error.

4. Uso de documentos

Después de ingresar al programa, elija si desea comprimir, descomprimir o salir del programa.

Archivo comprimido:

1) Mensaje: "¿Ingresar nombre de archivo?" Entrada: D:\cc\test.txt

2) Mensaje: "Comprimido ¿nombre del archivo?" Entrada: test.lzw

3) Pantalla: "Comprimiendo......" y "*" indican el progreso de la compresión del archivo.

Nota: Si el archivo ingresado no existe, el mensaje se repetirá hasta que se ingresen la ubicación y el nombre del archivo correctos. El test.lzw generado se almacenará en el directorio raíz del programa.

Por ejemplo: si el programa se coloca en D:\cc\, el archivo generado también estará en D:\cc\

Descompresión:

1) Consejos: "¿Ingresar nombre de archivo?" Entrada: test.lzw

2) Mensaje: "¿Nombre de archivo comprimido?" Entrada: test.txt

3) Pantalla: " Expandir......” y “*” indican el progreso de la descompresión del archivo.

Nota: Si el archivo ingresado no existe, el mensaje se repetirá hasta que se ingresen la ubicación y el nombre del archivo correctos. El test.lzw generado se almacenará en el directorio raíz del programa.

El archivo ANI (APPlicedon Startins Hour Glass) es un archivo de cursor animado para MS-Windows y su extensión de archivo es ".ani". Generalmente consta de cuatro partes: área de descripción de texto, área de información, área de control de tiempo y área de datos, que es el bloque ACONLIST. bloque anih, bloque de tarifas y bloque LISTA.

El siguiente es el contenido del archivo (datos E) y el diagrama de estructura estándar del archivo ANI (imagen) como ejemplo:

1. Desde (0000-006D) es el área de descripción de texto que forma parte del archivo ANI Wnd0WS 95 y NT

Si desea proporcionar una pequeña descripción de texto para el archivo ANI que desarrolló y agregar su información de derechos de autor, y al mismo tiempo, deben ser reconocidos por el software de reproducción de archivos ANI, esta es su única opción. Si cree que esto es problemático o que no hay nada que escribir, puede eliminar todo el contenido de este bloque y establecer el tamaño del bloque en 0. Recuerde, las dos partes del "Código de identificación de bloque

'ACONLIST'" y la identificación "Tamaño de bloque", que suman 12 bytes, no deben modificarse, moverse ni eliminarse, de lo contrario usted será responsable de las consecuencias. .

Quizás para sistematizar la información de descripción del texto, se incluyen varios subbloques en el bloque ACONLIST. Los dos utilizados en este ejemplo son: bloque INFOINAM (que proporciona explicaciones para este documento) y bloque IART (para. insertar información de versión). Para ser honesto, puede utilizar el método de insertar bloques personalizados en el archivo AVI para agregar sus propios bloques personalizados. El resultado es que el software de reproducción ANI lo trata como "BASURA".

0000-0003: Código de identificación del archivo multimedia: RIFF

0004-0007; Tamaño del archivo (2052h bytes) - 8 bytes

0008- 000F: bloque ACONLIST código de identificación, que es el signo del comienzo del área de descripción del texto

0010-0013: El tamaño del bloque ACONLIST (5Ah bytes)

0014-001B: Identificación del bloque INFOINAM código, signo El comienzo del subbloque de información de descripción del archivo

001C-001F: El tamaño del bloque INFOINAM (20h bytes)

0020-003F: El contenido del archivo descripción del subbloque de información "Inicio de la aplicaciónHour Glass"

0040-0043: código de identificación del bloque IART, que marca el comienzo de la información de la declaración de derechos de autor

0044-0047: tamaño del bloque IART (26 h bytes)

0048- 006D: La información de copyright se encuentra en el contenido del bloque "Microsoft Corporation, Copyright 1995"

2. ¿De (006E-0099)?