forked from gentilkiwi/mimikatz
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkull_m_cabinet.c
213 lines (196 loc) · 6.38 KB
/
kull_m_cabinet.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#include "kull_m_cabinet.h"
int DIAMONDAPI fnFilePlaced(PCCAB pccab, IN LPSTR pszFile, long cbFile, BOOL fContinuation, void FAR *pv)
{
return 0;
}
void HUGE * FAR DIAMONDAPI fnMemAlloc(ULONG cb)
{
return LocalAlloc(LPTR, cb);
}
void FAR DIAMONDAPI fnMemFree(void HUGE *memory)
{
LocalFree(memory);
}
INT_PTR FAR DIAMONDAPI fnFileOpen(IN LPSTR pszFile, int oflag, int pmode, int FAR *err, void FAR *pv)
{
HANDLE hFile;
DWORD dwDesiredAccess;
if(oflag & _O_RDWR)
dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
else if(oflag & _O_WRONLY)
dwDesiredAccess = GENERIC_WRITE;
else dwDesiredAccess = GENERIC_READ;
hFile = CreateFileA(pszFile, dwDesiredAccess, FILE_SHARE_READ, NULL, (oflag & _O_CREAT) ? CREATE_ALWAYS : OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE)
*err = GetLastError();
return (INT_PTR) hFile;
}
UINT FAR DIAMONDAPI fnFileRead(INT_PTR hf, void FAR *memory, UINT cb, int FAR *err, void FAR *pv)
{
DWORD dwBytesRead;
if(!ReadFile((HANDLE) hf, memory, cb, &dwBytesRead, NULL))
{
dwBytesRead = (DWORD) -1;
*err = GetLastError();
}
return dwBytesRead;
}
UINT FAR DIAMONDAPI fnFileWrite(INT_PTR hf, void FAR *memory, UINT cb, int FAR *err, void FAR *pv)
{
DWORD dwBytesWritten;
if(!WriteFile((HANDLE) hf, memory, cb, &dwBytesWritten, NULL))
{
dwBytesWritten = (DWORD)-1;
*err = GetLastError();
}
return dwBytesWritten;
}
int FAR DIAMONDAPI fnFileClose(INT_PTR hf, int FAR *err, void FAR *pv)
{
INT iResult = 0;
if(!CloseHandle((HANDLE) hf))
{
*err = GetLastError();
iResult = -1;
}
return iResult;
}
long FAR DIAMONDAPI fnFileSeek(INT_PTR hf, long dist, int seektype, int FAR *err, void FAR *pv)
{
INT iResult = 0;
iResult = SetFilePointer((HANDLE) hf, dist, NULL, seektype);
if(iResult == INVALID_SET_FILE_POINTER)
*err = GetLastError();
return iResult;
}
int FAR DIAMONDAPI fnFileDelete(IN LPSTR pszFile, int FAR *err, void FAR *pv)
{
INT iResult = 0;
if(!DeleteFileA(pszFile))
{
*err = GetLastError();
iResult = -1;
}
return iResult;
}
BOOL DIAMONDAPI fnGetTempFileName(OUT char *pszTempName, IN int cbTempName, void FAR *pv)
{
BOOL bSucceeded = FALSE;
CHAR pszTempPath[MAX_PATH], pszTempFile[MAX_PATH];
if(GetTempPathA(MAX_PATH, pszTempPath))
{
if(GetTempFileNameA(pszTempPath, "CABINET", 0, pszTempFile) != 0)
{
DeleteFileA(pszTempFile);
bSucceeded = SUCCEEDED(StringCbCopyA(pszTempName, cbTempName, pszTempFile));
}
}
return bSucceeded;
}
BOOL DIAMONDAPI fnGetNextCabinet(PCCAB pccab, ULONG cbPrevCab, void FAR *pv)
{
return SUCCEEDED(StringCchPrintfA(pccab->szCab, ARRAYSIZE(pccab->szCab), "%s_%02d.cab", pv, pccab->iCab));
}
long DIAMONDAPI fnStatus(UINT typeStatus, ULONG cb1, ULONG cb2, void FAR *pv)
{
return 0;
}
INT_PTR DIAMONDAPI fnGetOpenInfo(IN LPSTR pszName, USHORT *pdate, USHORT *ptime, USHORT *pattribs, int FAR *err, void FAR *pv)
{
HANDLE hFile;
FILETIME fileTime;
BY_HANDLE_FILE_INFORMATION fileInfo;
hFile = (HANDLE) fnFileOpen(pszName, _O_RDONLY, 0, err, pv);
if (hFile != INVALID_HANDLE_VALUE)
{
if(GetFileInformationByHandle(hFile, &fileInfo) && FileTimeToLocalFileTime(&fileInfo.ftCreationTime, &fileTime) && FileTimeToDosDateTime(&fileTime, pdate, ptime))
{
*pattribs = (USHORT) fileInfo.dwFileAttributes;
*pattribs &= (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH);
}
else
{
fnFileClose((INT_PTR) hFile, err, pv);
hFile = INVALID_HANDLE_VALUE;
}
}
return (INT_PTR) hFile;
}
LPCSTR FCIErrorToString(FCIERROR err)
{
switch (err)
{
case FCIERR_NONE:
return "No error";
case FCIERR_OPEN_SRC:
return "Failure opening file to be stored in cabinet";
case FCIERR_READ_SRC:
return "Failure reading file to be stored in cabinet";
case FCIERR_ALLOC_FAIL:
return "Insufficient memory in FCI";
case FCIERR_TEMP_FILE:
return "Could not create a temporary file";
case FCIERR_BAD_COMPR_TYPE:
return "Unknown compression type";
case FCIERR_CAB_FILE:
return "Could not create cabinet file";
case FCIERR_USER_ABORT:
return "Client requested abort";
case FCIERR_MCI_FAIL:
return "Failure compressing data";
default:
return "Unknown error";
}
}
PKIWI_CABINET kull_m_cabinet_create(LPSTR cabinetName)
{
PKIWI_CABINET cab = NULL;
if(cab = (PKIWI_CABINET) LocalAlloc(LPTR, sizeof(KIWI_CABINET)))
{
cab->ccab.cb = 0x4000000;
cab->ccab.cbFolderThresh = 0x4000000;
cab->ccab.setID = 42;
cab->ccab.iCab = 0;
cab->ccab.iDisk = 0;
if(fnGetNextCabinet(&cab->ccab, 0, cabinetName))
{
if(GetCurrentDirectoryA(ARRAYSIZE(cab->ccab.szCabPath), cab->ccab.szCabPath))
if(SUCCEEDED(StringCchCatA(cab->ccab.szCabPath, ARRAYSIZE(cab->ccab.szCabPath), "\\")))
if(!(cab->hfci = FCICreate(&cab->erf, fnFilePlaced, fnMemAlloc, fnMemFree, fnFileOpen, fnFileRead, fnFileWrite, fnFileClose, fnFileSeek, fnFileDelete, fnGetTempFileName, &cab->ccab, cabinetName)))
PRINT_ERROR(L"FCICreate failed with error code %d: %S\n", cab->erf.erfOper, FCIErrorToString((FCIERROR) cab->erf.erfOper));
}
else PRINT_ERROR(L"Failed to initialize the cabinet information structure.\n");
if(!cab->hfci)
cab = (PKIWI_CABINET) LocalFree(cab);
}
return cab;
}
BOOL kull_m_cabinet_add(PKIWI_CABINET cab, LPSTR sourceFile, OPTIONAL LPSTR destFile)
{
BOOL status = FALSE;
if(!destFile)
{
destFile = strrchr(sourceFile, '\\');
if(destFile)
destFile++;
else destFile = sourceFile;
}
if(!(status = FCIAddFile(cab->hfci, sourceFile, destFile, FALSE, fnGetNextCabinet, fnStatus, fnGetOpenInfo, TCOMPfromLZXWindow(21))))
PRINT_ERROR(L"FCIAddFile failed with error code %d: %S (%S -> %S)\n", cab->erf.erfOper, FCIErrorToString((FCIERROR) cab->erf.erfOper), sourceFile, destFile);
return status;
}
BOOL kull_m_cabinet_close(PKIWI_CABINET cab)
{
BOOL status = FALSE;
if(!(status = FCIFlushCabinet(cab->hfci, FALSE, fnGetNextCabinet, fnStatus)))
PRINT_ERROR(L"FCIFlushCabinet failed with error code %d: %S\n", cab->erf.erfOper, FCIErrorToString((FCIERROR) cab->erf.erfOper));
if(!FCIDestroy(cab->hfci))
PRINT_ERROR(L"FCIDestroy failed with error code %d: %S\n", cab->erf.erfOper, FCIErrorToString((FCIERROR) cab->erf.erfOper));
LocalFree(cab);
return status;
}