-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbatch.c
More file actions
172 lines (162 loc) · 5.34 KB
/
Copy pathbatch.c
File metadata and controls
172 lines (162 loc) · 5.34 KB
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
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <stdbool.h>
#define IDR_BIN 1234
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
char *temp, *batch;
int err = 0;
HANDLE hConsole;
#ifdef __cplusplus
extern "C"
{
#endif
bool MyDecryptFile(
LPTSTR szSource,
LPTSTR szDestination,
LPTSTR szPassword);
#ifdef __cplusplus
}
#endif
void clean()
{
// Delete extracted batch file, reset console colours and free dynamically allocated memory
DeleteFileA(temp);
DeleteFileA(strcat(strdup(temp), ".tmp"));
free(temp);
SetConsoleTextAttribute(hConsole, consoleInfo.wAttributes);
}
DWORD gettemp()
{
// Allow pseudo random string to be generated for the temp file name
srand(GetTickCount() * GetCurrentProcessId());
static char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-#'!";
size_t length = 10;
char *rndstr = NULL;
if (length)
{
rndstr = (char *)malloc(sizeof(char) * (length + 1));
if (rndstr)
{
for (int n = 0; n < length; n++)
{
int key = rand() % (int)(sizeof(charset) - 1);
rndstr[n] = charset[key];
}
rndstr[length] = '\0';
}
}
// Generate a unique file path to extract batch file to
temp = (char *)malloc(sizeof(char) * 1024);
// Get temp directory
GetTempPathA(1024, temp);
temp = (char *)realloc(temp, strlen(temp) + length + 10);
strcpy(temp, strcat(temp, strcat(rndstr, ".bat")));
free(rndstr);
temp = (char *)realloc(temp, strlen(temp) + 1);
// Allows startup() to check if the file already exists
return (GetFileAttributes(temp));
}
void startup()
{
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// Register exit protocols
atexit(clean);
// Generate temp file path and keep repeating until a unique name is found
while (gettemp() != INVALID_FILE_ATTRIBUTES && GetFileAttributes(strcat(temp, ".tmp")) != INVALID_FILE_ATTRIBUTES)
free(temp);
// Disable control C
SetConsoleCtrlHandler(NULL, TRUE);
// Save console attribute (colours)
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
}
void makebatch()
{
// Extract batch file to a hidden file at temp file location generated from gettemp()
HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDR_BIN), TEXT("BATCH"));
unsigned int batchsize = SizeofResource(NULL, hResource);
HGLOBAL hGlobal = LoadResource(NULL, hResource);
// Get a pointer to the file data
const char *lpData = (char *)LockResource(hGlobal);
FreeResource(hResource);
CloseHandle(hGlobal);
CloseHandle(hResource);
// Create hidden temp file using file path (this file will be saved as xxxx.bat.tmp)
HANDLE batchhandle = CreateFile(strcat(strdup(temp), ".tmp"), FILE_SHARE_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_TEMPORARY, NULL);
// Write encrypted data to file and check for errors
if (batchhandle == NULL || !WriteFile(batchhandle, lpData, batchsize, NULL, NULL))
{
printf("Unable To Create Resource Files: Error number %d\n", GetLastError());
err = err + 10;
}
CloseHandle(batchhandle);
MoveFileExA(strcat(strdup(temp), ".tmp"), NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
// Decrypt the data and delete the encrypted temp file (note this file can be decrypted if someone knows the password defined in Makefile so I recommend changing it there)
if (!MyDecryptFile(strcat(strdup(temp), ".tmp"), temp, PASSWORD))
{
printf("Unable To Read Resources : Error number %d\n", GetLastError());
err = err + 1;
}
DeleteFileA(strcat(strdup(temp), ".tmp"));
// Mark file for deletion after a reboot just in case the app is killed forcefully
MoveFileExA(temp, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
}
int runbatch()
{
// Create cmd process to run batch file and return exit code
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (0 == (CreateProcess(NULL, batch, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)))
{
printf("Unable To Create Child Process: Error number %d\n", GetLastError());
err = err + 100;
}
free(batch);
// If there were errors it will return the error code for the failed processes
if (err != 0)
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return err;
}
// Wait for batch file to exit
WaitForSingleObject(pi.hProcess, INFINITE);
// Get exit code for batch and return it to main
DWORD exit_code;
GetExitCodeProcess(pi.hProcess, &exit_code);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return exit_code;
}
int main(int argc, char *argv[])
{
startup();
char *args = strdup("");
if (argc > 1)
{
int i;
int intsize = strlen(argv[1]) + 2;
args = (char *)malloc(sizeof(char) * intsize);
// Copies first argument to variable
strcpy(args, argv[1]);
for (i = 2; i < argc; i++)
{
// Appends every other argument to variable with a space
intsize = intsize + strlen(argv[i]) + 5;
args = (char *)realloc(args, sizeof(char) * intsize);
sprintf(args, "%s %s", args, argv[i]);
}
}
// Generate final command to pass to CreateProcess
batch = (char *)malloc(strlen(temp) + strlen(argv[0]) + strlen(args) + 20);
sprintf(batch, "\"%s\" \"%s\" %s", temp, argv[0], args);
if (argc > 1)
free(args);
batch = (char *)realloc(batch, strlen(batch) + 1);
makebatch();
// Return final return value of batch to the main function
exit(runbatch());
}