-
Notifications
You must be signed in to change notification settings - Fork 0
/
nwc.cpp
152 lines (138 loc) · 4.39 KB
/
nwc.cpp
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
#include "nwc.hpp"
#ifdef _WIN32 //Windows 32/64-bit
#include <windows.h>
NWC_unsigned nwc_getfilesize(std::string filename)
{
NWC_unsigned filesize;
WIN32_FILE_ATTRIBUTE_DATA fadata;
GetFileAttributesExA((LPCSTR)filename.c_str(),GetFileExInfoStandard,&fadata);
filesize = (NWC_unsigned)fadata.nFileSizeLow | ((NWC_unsigned)fadata.nFileSizeHigh << 32);
return filesize;
}
#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) //*nix and Mac OS X
#include <sys/stat.h>
#include <unistd.h>
NWC_unsigned nwc_getfilesize(std::string filename)
{
NWC_unsigned filesize;
struct stat st;
stat(filename.c_str(),&st);
filesize = st.st_size;
return filesize;
}
#else //Other systems (requires a C++17 compiler and a working <filesystem> library)
#include <filesystem>
NWC_unsigned nwc_getfilesize(std::string filename)
{
NWC_unsigned filesize;
std::filesystem::path ipath;
ipath = filename;
filesize = std::filesystem::file_size(ipath);
return filesize;
}
#endif // _WIN32
int randomint(int imin,int imax)
{
std::uniform_int_distribution<int> dist(imin,imax);
return dist(mt);
}
char limittochar(int val)
{
return (char)((unsigned)val % 256);
}
void NWC_Class::run()
{
if(filename.empty())
{
printf("ERROR: No base file (-file) set, aborting...\n");
exit(NWCE_NOFILE);
}
if(output.empty())
{
output = "outfile"+std::to_string(randomint(1,INT_MAX));
printf("INFO: Output file will be %s\n",output.c_str());
}
if(everyxbyte==0) //everyxbyte has to be at least 1, as 0 would cause an infinite loop
{
everyxbyte=1;
}
if(cotype.type==CTPE_NONE)
{
printf("ERROR: No corruption type (add/shift/replace/random) set, aborting...\n");
exit(NWCE_NOCORR);
}
if(randseed!=0)
mt.seed(randseed);
std::vector<char> filevec;
std::ifstream ifs(filename,std::ios::binary);
if(ifs.is_open())
{
NWC_unsigned length = nwc_getfilesize(filename);
if(length==0)
{
printf("ERROR: Input file is empty\n");
exit(NWCE_IEMPTY);
}
filevec.resize(length);
ifs.read(filevec.data(),filevec.size()); //Fastest way to load a file to a std::vector<char>
ifs.close();
}
else
{
printf("ERROR: Input file can't be opened\n");
exit(NWCE_INOPEN);
}
if(filevec.size()==0)
{
printf("CRITICAL ERROR: Input file data is empty\n");
printf("Please report this error to the developer (Nightwolf-47)\n");
exit(NWCE_CRITID);
}
if(endbyte==NWC_EOFEND) //If endbyte is set to the end of file, set it to the last byte in the file
{
endbyte=filevec.size()-1;
}
endbyte = std::min(endbyte,(NWC_unsigned)filevec.size()-1);
for(NWC_unsigned byte=startbyte; byte<=endbyte; byte+=everyxbyte)
{
char& bytechar=filevec[byte];
switch(cotype.type)
{
case CTPE_ADD: //Add val_1 to byte. If the resulting value is higher than 255 or lower than 0, it wraps around
bytechar=limittochar((int)bytechar+(cotype.val_1 % 256)); //val_1 is converted to a value in range (-255,255) to prevent integer overflow
break;
case CTPE_SHIFT: //Swap current byte with byte that's val_1 bytes forward from it (this SHIFT implementation might change later)
if(cotype.val_1<0 && byte+cotype.val_1<0)
{
break;
}
else if(byte+cotype.val_1<=endbyte && byte+cotype.val_1>=startbyte)
{
std::swap(bytechar,filevec[byte+cotype.val_1]);
}
break;
case CTPE_REPLACE: //Replace byte with val_2 if it has val_1 value
if(cotype.val_1==(NWC_number)bytechar)
bytechar=cotype.val_2;
break;
case CTPE_RANDOM: //Randomize byte in range between val_1 and val_2
if(cotype.val_1>cotype.val_2)
std::swap(cotype.val_1,cotype.val_2);
bytechar = (char)(randomint(cotype.val_1,cotype.val_2));
break;
default:
break;
}
}
std::ofstream ofs(output,std::ios::binary);
if(ofs.is_open())
{
ofs.write(filevec.data(),filevec.size());
ofs.close();
}
else
{
printf("ERROR: Output file can't be opened\n");
exit(NWCE_ONOPEN);
}
}