게임
|
2026. 7. 18. 23:06
화이트데이1 언팩
작성일: 2019-06-29
url
CODE
/**
* Whiteday nop file Unpacker
* 다솜
* 본 코드를 사용하여 발생된 문제는 사용자에게 있습니다.
**/
//
// Lz77 알고리즘을 알려주신 단풍잎님 감사합니다 ^^
// 기타 나머지는 리버스 엔지니어링으로 알아내었습니다.
//
#include <stdio.h>
#include <string.h>
#include <direct.h>
#include <windows.h>
#include <conio.h>
#define BUFFER_SIZE (1024 * 1024 * 256)
/**
* BIG-SIZE buffer
**/
unsigned char *buff1;
unsigned char *buff2;
/**
* SONNORI Lz77 Xor Key
**/
unsigned short lz77_customkey[] = {
0xFF21, 0x834F, 0x675F, 0x0034, 0xF237, 0x815F, 0x4765, 0x0233
}; //65313 33615 26463 52 62007 33119 18277 563
//
// NOP file unpack~~~ *^^*
//
void nop_unpack(const char *nopFile)
{
enum e_noptype {
NOP_DATA_RAW = 0x00,
NOP_DATA_LZ77 = 0x01,
NOP_DATA_DIRECTORY = 0x02,
NOP_DATA_SONNORI_LZ77 = 0x03
};
FILE *fp, *out_fp;
int off, num, i, j;
unsigned char key;
fopen_s(&fp, nopFile, "rb");
if (!fp)
return;
/* the last byte value of NOP file must be 0x12 */
fseek(fp, -1, SEEK_END);
if (fgetc(fp) != 0x12) {
printf_s("* %-15s : 손상된 NOP 파일입니다.\\n", nopFile);
fclose(fp);
return;
}
/* NOP file header */
fseek(fp, -9, SEEK_END);
fread(&off, 4, 1, fp);
fread(&num, 4, 1, fp);
printf_s("* %-15s : 총 %d개의 데이터를 포함하고 있습니다.\\n", nopFile, num);
for (i = 0; i < num; ++i) {
unsigned char name[256];
unsigned char name_size;
unsigned char type;
int offset;
int encode_size;
int decode_size;
/* File infomation */
fseek(fp, off, SEEK_SET);
fread(&name_size, 1, 1, fp);
fread(&type, 1, 1, fp);
fread(&offset, 4, 1, fp);
fread(&encode_size, 4, 1, fp);
fread(&decode_size, 4, 1, fp);
fread(name, 1, name_size + 1, fp);
off += name_size + 15;
/**
* [ Data Type ]
* 0x00 : Raw
* 0x01 : Lz77 Compressed
* 0x02 : Directory
* 0x03 : SONNORI Lz77 Compressed
**/
/* In directory, this value used as file path decrypt key */
if (type == NOP_DATA_DIRECTORY) {
key = (char)decode_size;
}
else {
decode_size ^= key;
}
/* File path decrypt */
for (j = 0; j < name_size; ++j)
name[j] ^= key;
/* we doesn't have enough buffer size. so we skip this file. */
if (decode_size > BUFFER_SIZE) {
printf_s(" -> 실패 : %s ? ? ?\\n", name);
continue;
}
/* show current status with percent^^ */
printf_s("* %0.1f%% : %-68s\\r", ((float)i / (float)num * (float)100.0), name);
switch (type) {
case NOP_DATA_RAW:
{
fseek(fp, offset, SEEK_SET);
fread(buff1, 1, encode_size, fp);
fopen_s(&out_fp, name, "wb");
if (!out_fp) {
printf_s(" -> 실패 : %s ? ? ?\\n", name);
break;
}
fwrite(buff1, 1, decode_size, out_fp);
fclose(out_fp);
break;
}
case NOP_DATA_LZ77:
{
int bmask, bcnt = 0, size = 0, off, len;
unsigned short Lz77Info;
fseek(fp, offset, SEEK_SET);
fread(buff1, 1, encode_size, fp);
/* Lz77 uncompress */
for (j = 0; j < encode_size; bcnt = (bcnt + 1) & 0x07)
{
if (!bcnt) {
bmask = buff1[j++];
} else {
bmask >>= 1;
}
if (bmask & 0x01) {
Lz77Info = *(unsigned short *)&buff1[j], j += 2;
off = Lz77Info & 0x0FFF;
len = (Lz77Info >> 12) + 2;
memcpy(&buff2[size], &buff2[size - off], len);
size += len;
} else {
buff2[size++] = buff1[j++];
}
}
if (size != decode_size) {
printf_s(" -> 실패 : %s ? ? ?%d != %d\\n", name, size, decode_size);
break;
}
fopen_s(&out_fp, name, "wb");
if (!out_fp) {
printf_s(" -> 실패 : %s ? ? ?\\n", name);
break;
}
fwrite(buff2, 1, decode_size, out_fp);
fclose(out_fp);
break;
}
case NOP_DATA_DIRECTORY:
{
_mkdir(name);
break;
}
case NOP_DATA_SONNORI_LZ77:
{
int bmask, bsrcmask, bcnt = 0, size = 0, off, len;
unsigned short Lz77Info;
fseek(fp, offset, SEEK_SET);
fread(buff1, 1, encode_size, fp);
/* SONNORI Lz77 uncompress */
for (j = 0; j < encode_size; bcnt = (bcnt + 1) & 0x07)
{
if (!bcnt) {
bmask = bsrcmask = buff1[j++];
bmask ^= 0xC8;
}
else {
bmask >>= 1;
}
if (bmask & 0x01) {
Lz77Info = *(unsigned short *)&buff1[j], j += 2;
Lz77Info ^= lz77_customkey[(bsrcmask >> 3) & 0x07];
off = Lz77Info & 0x0FFF;
len = (Lz77Info >> 12) + 2;
memcpy(&buff2[size], &buff2[size - off], len);
size += len;
}
else {
buff2[size++] = buff1[j++];
}
}
if (size != decode_size) {
printf_s(" -> 실패 : %s ? ? ?%d != %d\\n", name, size, decode_size);
break;
}
fopen_s(&out_fp, name, "wb");
if (!out_fp) {
printf_s(" -> 실패 : %s ? ? ?\\n", name);
break;
}
fwrite(buff2, 1, decode_size, out_fp);
fclose(out_fp);
break;
}
default: // unknown type
printf_s(" -> 실패 : %s ? ? ?\\n", name);
break;
}
}
fclose(fp);
return;
}
int main(int argc, char *argv[])
{
/* 콘솔 속성 변경 */
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
/* 인트로 표시 */
SetConsoleTitle("NOPUnpack - http://c...content-available-to-author-only...r.com/wdlabyrinth");
printf_s("o------------------------------------------------------------------------------o");
printf_s("| W h i t e D a y :: A Labyrinth named school ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?|");
printf_s("o------------------------------------------------------------------------------o");
printf_s(" 네이버 카페 [화이트데이 게임 - 미궁의 열쇠] http://c...content-available-to-author-only...r.com/wdlabyrinth\\n");
printf_s(" 제작자: 다솜(Naver ID - love947345, MSN - eunju...@hotmail.com)\\n");
printf_s("o------------------------------------------------------------------------------o");
printf_s(" NOP파일을 풀어줍니다..^^\\n");
printf_s(" 화이트데이가 설치된 폴더에서 실행하시면, 게임실행에 문제가 생길 수 있습니다.\\n");
printf_s(" 계속 하실려면 아무키나 누르세요.\\n");
printf_s("o------------------------------------------------------------------------------o");
_getch();
/* 버퍼 메모리 할당 */
if (!(buff1 = (unsigned char *)malloc(BUFFER_SIZE)) || !(buff2 = (unsigned char *)malloc(BUFFER_SIZE))) {
printf_s("* 메모리 할당에 실패하였습니다.\\n");
getchar();
return 0;
}
char path[256];
int i;
/* 데모버전 NOP 파일 */
nop_unpack("whiteday.nop");
/* 데모버전 NOP 패치 파일 */
for (i = 100; i < 999; ++i) {
sprintf_s(path, sizeof(path), "patch%02d.nop", i);
nop_unpack(path);
}
/* 정식버전 NOP 패치 파일 */
for (i = 100; i < 999; ++i) {
sprintf_s(path, sizeof(path), "whiteday%03d.nop", i);
nop_unpack(path);
}
/* 오!재미 NOP 파일*/
for (i = 99; i < 999; ++i) {
sprintf_s(path, sizeof(path), "mod_beanbag%03d.nop", i);
nop_unpack(path);
}
/* 메모리 해제 */
free(buff2);
free(buff1);
printf_s("o------------------------------------------------------------------------------o");
printf_s(" 모든 작업이 끝났습니다. 종료하실려면 엔터키를 누르세요.\\n");
getchar();
return 0;
}
MAP


MODEL

IMAGE

HL1

HL2

'게임' 카테고리의 다른 글
| 붉은보석 기억용 (0) | 2026.07.18 |
|---|---|
| 데카론 (0) | 2026.07.18 |
| 포탈1 멀티 (0) | 2026.07.18 |
| Sudden Attack Full Source + Dev Tools (0) | 2026.07.18 |
FrostK
Writer개인 사이트 버리고 이곳으로 이주함