1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-03-24 18:16:24 +01:00

convert windows filesystem operations to unicode

This commit is contained in:
Brent Cook 2015-03-17 09:05:35 -05:00
parent f0eac5877a
commit 7c8b723c15
2 changed files with 183 additions and 45 deletions
c/meterpreter/source/extensions/stdapi/server/fs

@ -7,7 +7,7 @@
#ifdef _WIN32 #ifdef _WIN32
#define FS_SEPARATOR '\\' #define FS_SEPARATOR '\\'
#define FS_SEPARATOR_S "\\" #define FS_SEPARATOR_S "\\"
#define FS_MAX_PATH MAX_PATH #define FS_MAX_PATH 32768
#else #else
#define FS_SEPARATOR '/' #define FS_SEPARATOR '/'
#define FS_SEPARATOR_S "/" #define FS_SEPARATOR_S "/"

@ -3,30 +3,66 @@
#include "fs_local.h" #include "fs_local.h"
#include "precomp.h" #include "precomp.h"
static wchar_t *utf8_to_wchar(const char *in)
{
wchar_t *out;
int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, in, -1, NULL, 0);
if (len <= 0) {
return NULL;
}
out = calloc(len, sizeof(wchar_t));
if (out == NULL) {
return NULL;
}
if (MultiByteToWideChar(CP_UTF8, 0, in, -1, out, len) == 0) {
free(out);
out = NULL;
}
return out;
}
static char *wchar_to_utf8(const wchar_t *in)
{
char *out;
int len = WideCharToMultiByte(CP_UTF8, 0, in, -1, NULL, 0, NULL, NULL);
if (len <= 0) {
return NULL;
}
out = calloc(len, sizeof(char));
if (out == NULL) {
return NULL;
}
if (WideCharToMultiByte(CP_UTF8, 0, in, -1, out, len, NULL, FALSE) == 0) {
free(out);
out = NULL;
}
return out;
}
char * fs_expand_path(const char *regular) char * fs_expand_path(const char *regular)
{ {
DWORD expandedFilePathSize = 32768; wchar_t expanded_path[FS_MAX_PATH];
LPSTR expandedFilePath; wchar_t *regular_w;
/* regular_w = utf8_to_wchar(regular);
* Expand the file path if (regular_w == NULL) {
*/
expandedFilePath = malloc(expandedFilePathSize);
if (expandedFilePath == NULL) {
return NULL; return NULL;
} }
/* if (ExpandEnvironmentStringsW(regular_w, expanded_path, FS_MAX_PATH) == 0) {
* Expand the file path being accessed. ExpandEnvironmentStrings free(regular_w);
* NULL-terminates the result;
*/
if (ExpandEnvironmentStrings(regular, expandedFilePath,
expandedFilePathSize - 2) == 0) {
free(expandedFilePath);
return NULL; return NULL;
} }
return expandedFilePath; free(regular_w);
return wchar_to_utf8(expanded_path);
} }
int fs_ls(const char *directory, fs_ls_cb_t cb, void *arg) int fs_ls(const char *directory, fs_ls_cb_t cb, void *arg)
@ -35,8 +71,6 @@ int fs_ls(const char *directory, fs_ls_cb_t cb, void *arg)
LPSTR expanded = NULL; LPSTR expanded = NULL;
LPSTR baseDirectory = NULL; LPSTR baseDirectory = NULL;
char tempDirectory[FS_MAX_PATH]; char tempDirectory[FS_MAX_PATH];
WIN32_FIND_DATA data;
HANDLE ctx = NULL;
_snprintf(tempDirectory, sizeof(tempDirectory), "%s", directory); _snprintf(tempDirectory, sizeof(tempDirectory), "%s", directory);
@ -78,19 +112,25 @@ int fs_ls(const char *directory, fs_ls_cb_t cb, void *arg)
goto out; goto out;
} }
/* WIN32_FIND_DATAW data;
* Start the find operation wchar_t *path_w = utf8_to_wchar(expanded);
*/ if (path_w == NULL) {
ctx = FindFirstFile(expanded, &data); result = ERROR_NOT_ENOUGH_MEMORY;
goto out;
}
HANDLE ctx = FindFirstFileW(path_w, &data);
do { do {
if (ctx == INVALID_HANDLE_VALUE) { if (ctx == INVALID_HANDLE_VALUE) {
result = GetLastError(); result = GetLastError();
break; break;
} }
cb(arg, data.cFileName, baseDirectory); char *filename = wchar_to_utf8(data.cFileName);
cb(arg, filename, baseDirectory);
free(filename);
} while (FindNextFile(ctx, &data)); } while (FindNextFileW(ctx, &data));
/* /*
* Clean up resources * Clean up resources
@ -100,55 +140,135 @@ int fs_ls(const char *directory, fs_ls_cb_t cb, void *arg)
out: out:
free(tempDirectory); free(tempDirectory);
free(baseDirectory); free(baseDirectory);
free(path_w);
return result; return result;
} }
int fs_chdir(const char *directory) int fs_chdir(const char *directory)
{ {
if (SetCurrentDirectory(directory) == 0) { int rc = ERROR_SUCCESS;
return GetLastError(); wchar_t *dir_w = utf8_to_wchar(directory);
if (dir_w == NULL) {
rc = GetLastError();
goto out;
} }
return ERROR_SUCCESS;
if (SetCurrentDirectoryW(dir_w) == 0) {
rc = GetLastError();
}
out:
free(dir_w);
return rc;
} }
int fs_delete_dir(const char *directory) int fs_delete_dir(const char *directory)
{ {
if (RemoveDirectory(directory) == 0) { int rc = ERROR_SUCCESS;
return GetLastError(); wchar_t *dir_w = utf8_to_wchar(directory);
if (dir_w == NULL) {
rc = GetLastError();
goto out;
} }
return ERROR_SUCCESS;
if (RemoveDirectoryW(dir_w) == 0) {
rc = GetLastError();
}
out:
free(dir_w);
return rc;
} }
int fs_delete_file(const char *path) int fs_delete_file(const char *path)
{ {
if (DeleteFile(path) == 0) { int rc = ERROR_SUCCESS;
return GetLastError(); wchar_t *path_w = utf8_to_wchar(path);
if (path_w == NULL) {
rc = GetLastError();
goto out;
} }
return ERROR_SUCCESS;
if (DeleteFileW(path_w) == 0) {
rc = GetLastError();
}
out:
free(path_w);
return rc;
} }
int fs_getwd(char *directory, size_t len) int fs_getwd(char *directory, size_t len)
{ {
if (GetCurrentDirectory(len, directory) == 0) { int rc = ERROR_SUCCESS;
return GetLastError(); wchar_t *dir_w;
char *dir;
dir_w = calloc(len, sizeof(wchar_t));
if (dir_w == NULL) {
rc = GetLastError();
goto out;
} }
return ERROR_SUCCESS;
if (GetCurrentDirectoryW(len, dir_w) == 0) {
rc = GetLastError();
goto out;
}
dir = wchar_to_utf8(dir_w);
if (dir == NULL) {
rc = GetLastError();
goto out;
}
strncpy(directory, dir, len);
out:
free(dir);
free(dir_w);
return rc;
} }
int fs_move(const char *oldpath, const char *newpath) int fs_move(const char *oldpath, const char *newpath)
{ {
if (MoveFile(oldpath, newpath) == 0) { int rc = ERROR_SUCCESS;
return GetLastError(); wchar_t *old_w = utf8_to_wchar(oldpath);
wchar_t *new_w = utf8_to_wchar(newpath);
if ((old_w == NULL) || (new_w == NULL)) {
rc = GetLastError();
goto out;
} }
return ERROR_SUCCESS;
if (MoveFileW(old_w, new_w) == 0) {
rc = GetLastError();
}
out:
free(old_w);
free(new_w);
return rc;
} }
int fs_mkdir(const char *directory) int fs_mkdir(const char *directory)
{ {
if (CreateDirectory(directory, NULL) == 0) { int rc = ERROR_SUCCESS;
return GetLastError(); wchar_t *dir_w = utf8_to_wchar(directory);
if (dir_w == NULL) {
rc = GetLastError();
goto out;
} }
return ERROR_SUCCESS;
if (CreateDirectoryW(dir_w, NULL) == 0) {
rc = GetLastError();
}
out:
free(dir_w);
return rc;
} }
int fs_fopen(const char *path, const char *mode, FILE **f) int fs_fopen(const char *path, const char *mode, FILE **f)
@ -164,23 +284,41 @@ int fs_fopen(const char *path, const char *mode, FILE **f)
return ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY;
} }
*f = fopen(expanded, mode); wchar_t *path_w = utf8_to_wchar(expanded);
wchar_t *mode_w = utf8_to_wchar(mode);
if ((path_w == NULL) || (mode_w == NULL)) {
rc = ERROR_NOT_ENOUGH_MEMORY;
goto out;
}
*f = _wfopen(path_w, mode_w);
if (*f == NULL) { if (*f == NULL) {
rc = GetLastError(); rc = GetLastError();
} }
out:
free(expanded); free(expanded);
free(path_w);
free(mode_w);
return rc; return rc;
} }
int fs_stat(char *filename, struct meterp_stat *buf) int fs_stat(char *filename, struct meterp_stat *buf)
{ {
struct stat sbuf; struct _stat64i32 sbuf;
if (stat(filename, &sbuf) == -1) { wchar_t *filename_w = utf8_to_wchar(filename);
if (filename_w == NULL) {
return -1;
}
if (_wstat(filename_w, &sbuf) == -1) {
return GetLastError(); return GetLastError();
} }
free(filename_w);
buf->st_dev = sbuf.st_dev; buf->st_dev = sbuf.st_dev;
buf->st_ino = sbuf.st_ino; buf->st_ino = sbuf.st_ino;
buf->st_mode = sbuf.st_mode; buf->st_mode = sbuf.st_mode;