PDA

View Full Version : ACV Unpacker Reverse source



giangleloi
02-09-08, 09:28 PM
#include "zlib.h"
#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
#include "windows.h"
#include "tchar.h"
#include <locale.h>

char basedir[MAX_PATH] = "decompress";
int basedirlen = 0;
FILE *facv = NULL;
FILE *fp = NULL;
unsigned long dwFileCount = 0;
unsigned long ptr = 0;
unsigned long curid = 0;
BOOL unicode = FALSE;
unsigned int start_ptr = 4;
unsigned int each_block_size = 176;

BOOL FolderExist(char *strPath)
{
WIN32_FIND_DATA wfd;
BOOL rValue = FALSE;
char szPath[MAX_PATH] = {0};
HANDLE hFind = NULL;
FILE *tmp = NULL;

strcpy(szPath,strPath);
if (strlen(szPath) == 3 && ((szPath[0] >= 'A' && szPath[0] <= 'Z') || (szPath[0] >= 'a' && szPath[0] <= 'z')) && szPath[1] == ':')
{
return TRUE;
}else{
strcat(szPath,".");
}

hFind = FindFirstFile(szPath, &wfd);
if ((hFind != INVALID_HANDLE_VALUE) && (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
rValue = TRUE;
}
FindClose(hFind);
return rValue;
}

BOOL FileExist(char *strFileName)
{
WIN32_FIND_DATA wfd;
return FindFirstFile(strFileName, &wfd) != INVALID_HANDLE_VALUE;
}

BOOL CreateFolder(char *strPath)
{
SECURITY_ATTRIBUTES attrib;
attrib.bInheritHandle = FALSE;
attrib.lpSecurityDescriptor = NULL;
attrib.nLength = sizeof(SECURITY_ATTRIBUTES);
//ÉÏÃ涨ÒåµÄÊôÐÔ¿ÉÒÔÊ¡ÂÔ¡£ Ö±½Óreturn ::CreateDirectory( path, NULL); ¼´¿É
return CreateDirectory( strPath, &attrib);
}

void saveFile(char *fullpath,char *filename)
{
int l = 0;
int n = 0;
char *buf;
char *dbuf;
unsigned long flag = 0x64D8FE02;

printf("add file: %s ",filename);
fp = fopen(fullpath,"rb");
if (fp == NULL)
{
printf("Open file error!\n");
ExitProcess(0);
}
fseek(fp,0,SEEK_END);
l = ftell(fp);
fseek(fp,0,SEEK_SET);
n = compressBound(l);
buf = (char *)malloc(l);
if (buf == NULL)
{
printf("Allocate memroy error!\n");
ExitProcess(0);
}
dbuf = (char *)malloc(n);
if (dbuf == NULL)
{
printf("Allocate memroy error!\n");
free(buf);
ExitProcess(0);
}
fread(buf,l,sizeof(char),fp);
compress(dbuf,&n,buf,l);

fseek(facv,start_ptr+(curid++)*each_block_size,SEE K_SET);
fwrite(filename,160,sizeof(char),facv);
fwrite(&flag,sizeof(flag),1,facv);
fwrite(&n,sizeof(n),1,facv);
fwrite(&l,sizeof(l),1,facv);
fwrite(&ptr,sizeof(ptr),1,facv);

fseek(facv,start_ptr+each_block_size*dwFileCount+p tr,SEEK_SET);
fwrite(dbuf,n,sizeof(char),facv);
printf("compress len: %d\n",n);
ptr+=n;
free(buf);
free(dbuf);
fclose(fp);

//ExitProcess(0);
}

void saveFileW(wchar_t *wfullpath,wchar_t *wfilename)
{
int l = 0;
int n = 0;
char *buf;
char *dbuf;
unsigned long flag = 0x64D8FE02;
char filename[MAX_PATH];
HANDLE hFile;
DWORD dwlen;

ZeroMemory(filename,sizeof(filename));
WideCharToMultiByte(949, 0, wfilename, -1, filename, sizeof(filename), NULL, FALSE);

printf("add file: %s ",filename);

hFile = CreateFileW(wfullpath, GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == NULL)
{
printf("Open file error!\n");
ExitProcess(0);
}
l = GetFileSize(hFile, NULL);
n = compressBound(l);
buf = (char *)malloc(l);
if (buf == NULL)
{
printf("Allocate memroy error!\n");
ExitProcess(0);
}
dbuf = (char *)malloc(n);
if (dbuf == NULL)
{
printf("Allocate memroy error!\n");
free(buf);
ExitProcess(0);
}
ReadFile(hFile,buf,l,&dwlen,NULL);
compress(dbuf,&n,buf,l);

fseek(facv,start_ptr+(curid++)*each_block_size,SEE K_SET);
fwrite(filename,160,sizeof(char),facv);
fwrite(&flag,sizeof(flag),1,facv);
fwrite(&n,sizeof(n),1,facv);
fwrite(&l,sizeof(l),1,facv);
fwrite(&ptr,sizeof(ptr),1,facv);

fseek(facv,start_ptr+each_block_size*dwFileCount+p tr,SEEK_SET);
fwrite(dbuf,n,sizeof(char),facv);
printf("compress len: %d\n",n);
ptr+=n;
free(buf);
free(dbuf);
CloseHandle(hFile);
}

void EnumFile(char *strPath)
{
WIN32_FIND_DATA wfd;
char szPath[MAX_PATH] = {0};
char szTmpPath[MAX_PATH] = {0};
HANDLE hFind = NULL;
FILE *tmp = NULL;

strcpy(szPath,strPath);
strcat(szPath,"*");

hFind = FindFirstFile(szPath, &wfd);
if ((hFind != INVALID_HANDLE_VALUE))
{
if (strlen(wfd.cFileName) && *wfd.cFileName == '.')
{
FindNextFile(hFind,&wfd);
while (FindNextFile(hFind,&wfd))
{
ZeroMemory(szTmpPath,MAX_PATH);
strcpy(szTmpPath,strPath);
strcat(szTmpPath,wfd.cFileName);
if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
strcat(szTmpPath,"\\");
EnumFile(szTmpPath);
}else
{
saveFile(szTmpPath,szTmpPath+basedirlen);
}
}
}

}
FindClose(hFind);
}

void EnumFileW(wchar_t *strPath)
{
WIN32_FIND_DATAW wfd;
wchar_t szPath[MAX_PATH] = {0};
wchar_t szTmpPath[MAX_PATH] = {0};
HANDLE hFind = NULL;
FILE *tmp = NULL;

wcscpy(szPath,strPath);
wcscat(szPath,L"*");

hFind = FindFirstFileW(szPath, &wfd);
if ((hFind != INVALID_HANDLE_VALUE))
{
if (wcslen(wfd.cFileName) && *wfd.cFileName == _TEXT('.'))
{
FindNextFileW(hFind,&wfd);
while (FindNextFileW(hFind,&wfd))
{
ZeroMemory(szTmpPath,MAX_PATH);
wcscpy(szTmpPath,strPath);
wcscat(szTmpPath,wfd.cFileName);
if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
wcscat(szTmpPath,L"\\");
EnumFileW(szTmpPath);
}else
{
saveFileW(szTmpPath,szTmpPath+basedirlen);
}
}
}

}
FindClose(hFind);
}

int EnumFileCount(char *strPath)
{
WIN32_FIND_DATA wfd;
char szPath[MAX_PATH] = {0};
char szTmpPath[MAX_PATH] = {0};
HANDLE hFind = NULL;
FILE *tmp = NULL;
DWORD fileCount=0;

strcpy(szPath,strPath);
strcat(szPath,"*");

hFind = FindFirstFile(szPath, &wfd);
if ((hFind != INVALID_HANDLE_VALUE))
{
if (strlen(wfd.cFileName) && *wfd.cFileName == '.')
{
FindNextFile(hFind,&wfd);
while (FindNextFile(hFind,&wfd))
{
strcpy(szTmpPath,strPath);
strcat(szTmpPath,wfd.cFileName);
if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
strcat(szTmpPath,"\\");
fileCount+=EnumFileCount(szTmpPath);
}else
{
fileCount++;
}
}
}

}
FindClose(hFind);
return fileCount;
}

void gendir(char *file)
{
char dir[MAX_PATH];
int i,l;

l=strlen(file);
for (i=0;i<l;i++)
{
if (file[i] == '\\')
{
memset(dir,0,MAX_PATH);
strcpy(dir,basedir);
memcpy(dir+basedirlen,file,i);
if (!FolderExist(dir))
{
printf("generate folder: %s...",dir);
if (CreateFolder(dir))
{
printf("OK.\n");
}else
{
printf("Failure.\nThe program break.\n");
ExitProcess(0);
}
}
}
}
}

int main(int argc, char* argv[])
{
long file_num = 0;
char filename[180];
char szfile[MAX_PATH];
unsigned long compress_len,filelen,ptr;
long i=0;
char *compdata = NULL;
char *buf = NULL;
DWORD startTime = GetTickCount();
BOOL listmode = FALSE;
BOOL packmode = FALSE;
char c = 0;
int k=0;
char acv_file[MAX_PATH] = {0};
BOOL baseupdated = FALSE;
wchar_t szUniBuf[MAX_PATH];
HANDLE hFile = NULL;
DWORD dwlen = 0;
DWORD flag = 0;
DWORD tmp_flag = 0;
int xi;
unsigned char detFlag[4] = {0};

printf("acv file tools optimize version\n");
<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>

if (argc > 1)
{
for (i=1;i<argc;i++)
{
if (argv[i][0] == '-')
{
switch (argv[i][1])
{
case 'l': listmode=TRUE; break;
case 'c': packmode=TRUE; break;
case 'u': unicode=TRUE; break;
}
}else
{
switch (k++)
{
case 0: strcpy(acv_file,argv[i]); break;
case 1: strcpy(basedir,argv[i]); baseupdated = TRUE; break;
}
}
}
}

if (argc == 1 || strlen(acv_file) == 0 || (packmode && !baseupdated))
{
printf("usage: acv_tool avcfilename [basedir] [option]\n");
printf("option:\n");
printf("-l list file only.\n");
printf("-c compress mode.\n");
printf("-u unicode mode.\n");
printf("\nexample:\n");
printf("acv_tool 001.acv dec decompress 001.acv to dec folder.\n");
printf("acv_tool 001.acv dec -c compress dec folder to 001.acv.\n");
printf("acv_tool 001.acv -l get the file list for 001.acv.\n");
return 0;
}

if (basedir[strlen(basedir)-1] != '\\'){
strcat(basedir,"\\");
}
basedirlen = strlen(basedir);

if (packmode)
{
if (!FolderExist(basedir))
{
printf("base directory not exists!\n");
return 0;
}
if (FileExist(acv_file))
{
printf("File exists! Replace the acv file? [Y/n]");
c = getch();
printf("\n");
if (c != 'y' && c != 'Y' && c != 13)
{
return 1;
}
}
dwFileCount = EnumFileCount(basedir);
facv = fopen(acv_file,"wb");
if (facv == NULL)
{
printf("Save file error!\n");
return 0;
}
fwrite(&dwFileCount,sizeof(dwFileCount),1,facv);
if (unicode)
{
MultiByteToWideChar(949, 0, basedir, -1, szUniBuf, sizeof(szUniBuf));
EnumFileW(szUniBuf);
}else
{
EnumFile(basedir);
}
fclose(facv);
}else
{
if (!FolderExist(basedir))
{
printf("base directory not exists! automatic create a new folder...");
if (CreateFolder(basedir))
{
printf("OK.\n");
}else
{
printf("Failure.\nThe program break.");
return 0;
}
}

facv = fopen(acv_file,"rb");
if (facv == NULL)
{
printf("read file error!\n");
return 0;
}
printf("File version: ");
fread(detFlag,sizeof(char),4,facv);
if (detFlag[2] == 0x01 && detFlag[3] == 0xFF)
{
start_ptr = 8;
each_block_size = 180;
printf("1.1\n");
}else
{
printf("1.0\n");
}
printf("ptr: %d each_block_size:%d\n",start_ptr,each_block_size);
fseek(facv,start_ptr-4,SEEK_SET);
fread(&file_num,sizeof(long),1,facv);
printf("file num: %u\n",file_num);
for (i=0;i<file_num;i++)
{
fseek(facv,start_ptr+i*each_block_size,SEEK_SET);
fread(filename,sizeof(char),each_block_size,facv);

memcpy(&flag,filename+160,4);
memcpy(&compress_len,filename+164,4);
memcpy(&filelen,filename+168,4);
memcpy(&ptr,filename+172,4);
if (each_block_size == 180) memcpy(&tmp_flag,filename+176,4);
//printf("flag: %x\n",tmp_flag); // same as the file first
if (!listmode)
{
compdata = (char *)malloc(compress_len+1);
if (compdata == NULL)
{
printf("allocate memroy error!\n");
break;
}
buf = (char *)malloc(filelen);
if (buf == NULL)
{
printf("allocate memroy error!\n");
free(compdata);
break;
}
fseek(facv,start_ptr+file_num*each_block_size+ptr, SEEK_SET);
//compdata[0]=0x78;
//compdata[1] = 0x9C;
fread(compdata,compress_len,sizeof(char),facv);

if (uncompress(buf,&filelen,compdata,compress_len) != 0)
{
printf("decompress Error!\n");
return 0;
}

gendir(filename);

memcpy(szfile,basedir,basedirlen+1);
strcat(szfile,filename);

if (unicode)
{
MultiByteToWideChar(949, 0, szfile, -1, szUniBuf, sizeof(szUniBuf));
hFile = CreateFileW(szUniBuf, GENERIC_WRITE, FILE_SHARE_DELETE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, buf, filelen, &dwlen, NULL);
CloseHandle(hFile);
}else
{
fp = fopen(szfile,"wb");
if (fp != NULL)
{
fwrite(buf, filelen, sizeof(char), fp);
//fwrite(compdata, compress_len, sizeof(char), fp);
fclose(fp);
}else
{
printf("Write file: %s failure.\n");
free(buf);
break;
}
}
free(compdata);
free(buf);
//if (i==2) break;
}

printf("file: %s\tc_len:%u flag: %u size:%u pt: %u\n",filename,compress_len,flag,filelen,ptr);
//WideCharToMultiByte(949, 0, szUniBuf, -1, filename, sizeof(filename), NULL, FALSE);
}
fclose(facv);
} // PACK MDOE
printf("Process in %d ms.\n",GetTickCount()-startTime);
return 0;ngồn của rz,có thể dùng c++ để làm 1 program,đây chỉ unpack dc acv cũ chưa thử acv mới:big_smile:

KidA7
05-09-08, 10:46 AM
Kiếm thêm cái bộ thư viện .h và .lib của zlib rồi hãy post nhé

KidA7
12-09-08, 04:37 PM
Đầu tiên là tải bộ này về:
<b><font color=red>[Chỉ có thành viên mới xem link được. <a href="register.php"> Nhấp đây để đăng ký thành viên......</a>]</font></b>
Giải nén ra, copy zlib.h và zconf vào thư mục include của chỗ cài đặt C++, Hoặc trong phần properties của project chọn đường dẫn ở phần addition include gì đó tới thư mục incude giải nén ra.

Phần linker của project properties thì chỉ tới file zdll.lib hoặc copy file đó và thư mục lib của C++

Nếu dùng C++6.0 thì thế là đủ. Còn nếu dùng C++ 2005 thì thêm công đoạn sửa mấy cái như từ char *buf sang Byte *buf và các chỗ khác tương tự. Cả với int u => uLongf u, trong phần character set chọn un set hoặc multi character set. Biên dịch nó báo khoảng 30 warning. Nhưng cái này chạy tốt hơn bản acv_tool đầu tiên vì được mấy anh như vnsercurity và PassZai bên Auclan sửa đổi rồi. (nó sẽ báo phiên bản khi gặp acv mới và không unpack). Các bạn có thể phát triển một số chức năng thêm như :
- Tìm xem một file ở trong file nén acv nào.
- Nối 2 file acv với nhau (tự động loại bỏ các file trùng, nhận diện phiên bản acv để add)
- Unpack một thư mục chỉ định
- List acv ra một file .txt để xem chi tiết.
>_< chúc các bạn thành công

hellokytty
12-09-08, 04:45 PM
Chà chà, thế Kid có thể làm tool unpack acv mới được không? Làm cho anh em đi. ^^

LiKMaMa
17-09-08, 12:19 PM
Ơ thế làm tool unpack acv mới có Unpack đc mấy cai .acv của Au Korea ko ? Thèm cái .acv của nó quá mà ko làm sao Unpack đc ?