There is a device sending byte stream using UTF-8. Among them ESC symbols present, such as 0x1B[?25h 0x1B[nJ 0x1B[u etc. which are later printed with std::cout.
How to force std::cout to discard this ANSI escape code sequencies in printing outside?
Since I am working with Qt's QSerialPort I will convey the code I made according this enviroment
void removeCtrlSeq(QByteArray &data)
{
char csi = 0x1B;
if (data.contains(csi))
{
bool inSearchForSci = true; // flag of search activity (CSI symbol)
unsigned int p = 0;
for (unsigned int s = 0; s < data.length(); ++s)
{
if (inSearchForSci == true && static_cast<unsigned char>(data[s]) == csi)
{
inSearchForSci = false; // here we found the begining of sequence - so we freez search for future steps
}
else
{
if (inSearchForSci == false && ((static_cast<unsigned char>(data[s]) >= 0x41 && static_cast<unsigned char>(data[s]) <= 0x5A) ||
(static_cast<unsigned char>(data[s]) >= 0x61 && static_cast<unsigned char>(data[s]) <= 0x7A)))
{
inSearchForSci = true; // here we found the end of sequence - so make search active again
s++;
continue;
}
}
if (inSearchForSci == true)
{
data[p++] = data[s];
}
}
data.resize(p);
}
}
Related
I want to pause my program on the 0x32, 0x33 and 0x34 key and make it work again on the 0x31 key, how can I? I used this code to pause on the 0x32 key, it's working, but I can't get it back to work on the desired key
To summarize what #user4581301 suggested:
#include <conio.h>
...
if (GetAsyncKeyState(0x32) || GetAsyncKeyState(0x33) || GetAsyncKeyState(0x34)) {
while (_getch() != 0x31)
;
}
If your application is a console application, I implemented the function you want through loop. If it's a desktop application, you can refer to my code logic.
#include <iostream>
#include<cstdlib>
#include<time.h>
#include<Windows.h>
#include<conio.h>
using namespace std;
int main()
{
while (true) {
for (int i = 0; i < 5; ++i) {
if (GetAsyncKeyState(gun_keys[i]) && (gun != guns[i])) {
gun = guns[i];
system("cls");
gun_delay = GetTime(gun->rpm);
gun_index = 0;
break;
}
}
if (GetAsyncKeyState(VK_DELETE)) //Bind key, what close this program
{
ExitProcess(-1); //Exit Process
}
if (GetAsyncKeyState(MOUSEEVENTF_MOVE) < 0) {
if (!is_mouse_down) {
is_mouse_down = true;
if (gun != nullptr)
gun_index = 0;
}
if (gun != nullptr && gun_index != gun->len) {
mouse_event(MOUSEEVENTF_MOVE, long(gun->pattner[gun_index][0] * K), long(gun->pattner[gun_index][1] * K), 0, 0);
++gun_index;
Sleep(gun_delay);
continue;
}
}
else
is_mouse_down = false;
if (_kbhit())//Checks if there is currently keyboard input and returns a non-zero value if there is, or 0 otherwise
{
int ch = _getch();
if (ch == 0x32 || ch == 0x33 || ch == 0x34)
{
ch = _getch();//It waits for input and pauses the program
}
if (ch != 0x31)
{
while (true)
{
if (_kbhit())
{
int ch = _getch();
if (ch == 0x31) break;
}
}
}
fflush(stdin);//Clear the input buffer
}
Sleep(150);
}
return 0;
}
My program crashes every time when I try to run the code in this link. The problem seems to be in this line *((char*)&configuration + i) = (char)EEPROM.read(i);. I think there is no need to allocate memory for variable configuration since the variable configuration is already initialized.
int loadconfig() {
if(EEPROM.read(0) == config_ver[0] && EEPROM.read(1) == config_ver[1] &&
EEPROM.read(2) == config_ver[2] && EEPROM.read(3) == config_ver[3]) {
for(int i = 0; i <= sizeof(configuration_type); i++) {
*((char*)&configuration + i) = (char)EEPROM.read(i); //<------problem
}
return 1;
}
return 0;
}
Whole code from the link:
#include <EEPROM.h>
#define CONFIG_VERSION "VER01"
// Where in EEPROM?
#define CONFIG_START 32
typedef struct
{
char version[6]; // detect if setting actually are written
int my_setting_integer;
} configuration_type;
// with DEFAULT values!
configuration_type CONFIGURATION = {
CONFIG_VERSION,
42
};
// load whats in EEPROM in to the local CONFIGURATION if it is a valid setting
int loadConfig() {
// is it correct?
if (EEPROM.read(CONFIG_START + 0) == CONFIG_VERSION[0] &&
EEPROM.read(CONFIG_START + 1) == CONFIG_VERSION[1] &&
EEPROM.read(CONFIG_START + 2) == CONFIG_VERSION[2] &&
EEPROM.read(CONFIG_START + 3) == CONFIG_VERSION[3] &&
EEPROM.read(CONFIG_START + 4) == CONFIG_VERSION[4]){
// load (overwrite) the local configuration struct
for (unsigned int i=0; i<sizeof(CONFIGURATION); i++){
*((char*)&CONFIGURATION + i) = EEPROM.read(CONFIG_START + i);
}
return 1; // return 1 if config loaded
}
return 0; // return 0 if config NOT loaded
}
// save the CONFIGURATION in to EEPROM
void saveConfig() {
for (unsigned int i=0; i<sizeof(CONFIGURATION); i++)
EEPROM.write(CONFIG_START + i, *((char*)&CONFIGURATION + i));
}
void setup() {
Serial.begin(9600);
Serial.println("Hello world!"); // prints hello with ending line break
if(loadConfig()){
Serial.println("Config loaded:");
Serial.println(CONFIGURATION.version);
Serial.println(CONFIGURATION.my_setting_integer);
}else{
Serial.println("Config not loaded!");
saveConfig(); // overwrite with the default settings
}
}
void loop() {
//every 5s increment and save the settings!
delay(5000);
CONFIGURATION.my_setting_integer++;
saveConfig();
}
It is the "<=" in the for loop.
Change it to "<" and try again.
Hint: Typical Buffer Overflow problem
I thought it would be a good best practice to search thru my code for any references like ..
char buf[MAX_STRING_LENGTH];
... and replace them with ...
char buf[MAX_STRING_LENGTH] = {'\0'};
Doing a search in the code I have a number that are set to null (around 239) and others that are not (1,116).
When I replaced the remaining 1,116 instances with char buf[MAX_STRING_LENGTH] = {'\0'}; and pushed the code live the game was noticeably laggy.
Reverting the change removed the lag.
Can someone explain why setting these to null would cause the game to lag while running?
Example code setting to Null
void do_olist(Character *ch, char *argument, int cmd)
{
int header = 1;
int type = -1;
int wear_bit = -1;
int i = 0;
int inclusive;
int zone = -1;
int yes_key1 = 0;
int yes_key2 = 0;
int yes_key3 = 0;
int count = 0;
Object *obj;
bool found = false;
char key1 [MAX_STRING_LENGTH] = {'\0'};
char key2 [MAX_STRING_LENGTH] = {'\0'};
char key3 [MAX_STRING_LENGTH] = {'\0'};
char buf [MAX_STRING_LENGTH];
argument = one_argument(argument, buf);
if (!*buf)
{
ch->send("Selection Parameters:\n\n");
ch->send(" +/-<object keyword> Include/exclude object keyword.\n");
ch->send(" <zone> Objects from zone only.\n");
ch->send(" <item-type> Include items of item-type.\n");
ch->send(" <wear-bits> Include items of wear type.\n");
ch->send("\nExample: olist +sword -rusty weapon 10\n");
ch->send("will only get non-rusty swords of type weapon from zone 10.\n");
return;
}
while (*buf)
{
inclusive = 1;
if (strlen(buf) > 1 && isalpha(*buf) &&
(type = index_lookup(item_types, buf)) != -1)
{
argument = one_argument(argument, buf);
continue;
}
if (strlen(buf) > 1 && isalpha(*buf) &&
(wear_bit = index_lookup(wear_bits, buf)) != -1)
{
argument = one_argument(argument, buf);
continue;
}
if (isdigit(*buf))
{
if ((zone = atoi(buf)) >= MAX_ZONE)
{
ch->send("Zone not in range 0..99\n");
return;
}
argument = one_argument(argument, buf);
continue;
}
switch (*buf)
{
case '-':
inclusive = 0;
case '+':
if (!buf [1])
{
ch->send("Expected keyname after 'k'.\n");
return;
}
if (!*key1)
{
yes_key1 = inclusive;
strcpy(key1, buf + 1);
}
else if (!*key2)
{
yes_key2 = inclusive;
strcpy(key2, buf + 1);
}
else if (*key3)
{
ch->send("Sorry, at most three keywords.\n");
return;
}
else
{
yes_key3 = inclusive;
strcpy(key3, buf + 1);
}
break;
case 'z':
argument = one_argument(argument, buf);
if (!isdigit(*buf) || atoi(buf) >= MAX_ZONE)
{
ch->send("Expected valid zone after 'z'.\n");
return;
}
zone = atoi(buf);
break;
}
argument = one_argument(argument, buf);
}
*b_buf = '\0';
for (obj = full_object_list; obj; obj = obj->lnext)
{
if (zone != -1 && obj->zone != zone)
continue;
if (type != -1 && obj->obj_flags.type_flag != type)
continue;
if (wear_bit != -1)
{
for (i = 0; (*wear_bits[i] != '\n'); i++)
{
if (IS_SET(obj->obj_flags.wear_flags, (1 << i)))
{
if (i != wear_bit)
continue;
else
found = true;
}
}
if (found)
found = false;
else
continue;
}
if (*key1)
{
if (yes_key1 && !strcasestr(const_cast<char*> (obj->getName().c_str()), key1))
continue;
else if (!yes_key1 && strcasestr(const_cast<char*> (obj->getName().c_str()), key1))
continue;
}
if (*key2)
{
if (yes_key2 && !strcasestr(const_cast<char*> (obj->getName().c_str()), key2))
continue;
else if (!yes_key2 && strcasestr(const_cast<char*> (obj->getName().c_str()), key2))
continue;
}
if (*key3)
{
if (yes_key3 && !strcasestr(const_cast<char*> (obj->getName().c_str()), key3))
continue;
else if (!yes_key3 && strcasestr(const_cast<char*> (obj->getName().c_str()), key3))
continue;
}
count++;
if (count < 200)
olist_show(obj, type, header);
header = 0;
}
if (count > 200)
{
sprintf(buf, "You have selected %d objects (too many to print all at once).\n",
count);
ch->send(buf);
//return;
}
else {
sprintf(buf, "You have selected %d objects.\n",
count);
ch->send(buf);
}
page_string(ch->desc, b_buf);
}
I took the advice to replace instances of ...
char buf[MAX_STRING_LENGTH] = {'\0'};
with ...
char buf[MAX_STRING_LENGTH]; *buf = 0;
I am trying to make a detour using MSDN Detours 3.0 to register text drawn by ExtTextOut() from a third party software. I have created a DLL which I inject in the target software. When I detour ExtTextOut I try to copy the string sent to the method and read the text to a textfile in modified format. Since the input string is UTF-16 and I am only interested in keeping the ASCII characters lower than 127 I have made some logic for this.
The problem is, though, that my program crashes a while after it is injected in the target. I suspect that it might have something to do with the malloc function.
If I use malloc to locate memory in a process, can I guaratee that this will not override any memory in the target process? If that would be the case, how can I create a function to make sure that my malloc wont interfere with the target process.
The code:
BOOL WINAPI Mine_ExtTextOut(HDC hdc, int X, int Y, UINT options, RECT* lprc, LPCWSTR text, UINT cbCount, INT* lpSpacingValues)
{
//
if(reinterpret_cast<const char*>(text)[0] == '>'){
//wstring_convert<codecvt_utf8_utf16<wchar_t>,wchar_t> convert;
//string utf8_string = convert.to_bytes(text);
//int n = utf8_string.length();
int n = cbCount;
char *buffer = (char*) malloc (n+1);
char *bufferCopy = (char*) malloc (n+1);
for (int i=0; i<n; i++){
if((long) text[i] > 127){
buffer[i] = ' ';
continue;
}
buffer[i]= (char) text[i];
}
buffer[n]='\0';
bool wasBlank = false;
int ix = 0;
for(int i = 0; i<n; ++i){
if(buffer[i] == ' '){
if(wasBlank || i < 2) continue;
bufferCopy[ix++] = buffer[i];
wasBlank = true;
continue;
}
wasBlank = false;
if(buffer[i] == '>') continue;
bufferCopy[ix++] = buffer[i];
}
bufferCopy[ix]='\0';
ofstream myFile;
myFile.open("C:\\temp\\textHooking\\textHook\\example2.txt", ios::app);
if(buffer[0] == '>'){
//myFile.write(reinterpret_cast<const char*>(text), cbCount*sizeof(*text));
myFile.write(bufferCopy, ix*sizeof(*bufferCopy));
myFile << endl;
}
free(buffer);
free(bufferCopy);
}
BOOL rv = Real_ExtTextOut(hdc, X, Y, options, lprc, text, cbCount, lpSpacingValues);
return rv;
}
The cbCount parameter of ExtTextOut() is expressed in characters, but the input parameter of malloc() is expressed in bytes. You are hooking the Unicode version of ExtTextOut() (aka ExtTextOutW()), where sizeof(WCHAR) is 2 bytes. You are trying to treat the input string as Ansi, which it is not, and you are not taking UTF-16 surrogates into account.
To do what you are attempting, you need to actually decode the UTF-16 data into Unicode codepoints first before deciding which ones to keep, eg:
BOOL WINAPI Mine_ExtTextOut(HDC hdc, int X, int Y, UINT options, RECT* lprc, LPCWSTR text, UINT cbCount, INT* lpSpacingValues)
{
if ((cbCount > 0) && (text != NULL) && (text[0] == L'>'))
{
// worse case, every UTF-16 character is ASCII and will be kept,
// so allocate enough memory for at least that many characters
std::string buffer(cbCount);
std::string bufferCopy(cbCount);
int ix1 = 0;
for (UINT i = 0; i < cbCount;)
{
ULONG c;
// is it a UTF-16 high surrogate?
if ((text[i] >= 0xD800) && (text[i] <= 0xDBFF))
{
// is it at the end of the string?
if ((i+1) == cbCount)
{
// malformed surrogate
break;
}
// is it followed by a UTF-16 low surrogate?
if ((text[i+1] < 0xDC00) || (text[i+1] > 0xDFFF))
{
// malformed surrogate
break;
}
// decode the surrogate and skip past it
c = ((ULONG(text[i] - 0xD800) << 10) | ULONG(text[i+1] - 0xDC00)) + 0x10000;
i += 2;
}
// is it a UTF-16 low surrogate?
else if (text[i] >= 0xDC00) && (text[i] <= 0xDFFF))
{
// malformed surrogate
break;
}
// must be a non-surrogated character
else
{
c = (ULONG) text[i];
++i;
}
// keep it?
if( c > 127 )
buffer[ix1] = ' ';
else
buffer[ix1] = (char) c;
++ix1;
}
bool wasBlank = false;
int ix2 = 0;
for(int i = 0; i < ix1; ++i)
{
if (buffer[i] == ' ')
{
if (wasBlank || (i < 2)) continue;
bufferCopy[ix2++] = buffer[i];
wasBlank = true;
continue;
}
wasBlank = false;
if (buffer[i] == '>') continue;
bufferCopy[ix2++] = buffer[i];
}
ofstream myFile;
myFile.open("C:\\temp\\textHooking\\textHook\\example2.txt", ios::app);
if (myFile)
{
myFile.write(bufferCopy.c_str(), ix2);
myFile << endl;
}
}
return Real_ExtTextOut(hdc, X, Y, options, lprc, text, cbCount, lpSpacingValues);
}
Based on the comments here are a few things you could do to try to narrow this down:
Replace malloc: Instead use buffer= (char *)GlobalAlloc(GPTR, n+1); and GlobalFree(buffer). This would make sure it's not a problem with having multiple c-runtime libraries.
Alternately, to make sure there are no situations where you run over the bounds of the allocated buffers, try to malloc a lot more, e.g. buffer= malloc(n+1024); and see if that fixes the problem. If that does, you'll need to comb through your code if you go beyond the valid offsets in the buffers.
A similar approach (for testing) would be to use stack versions of the buffer that are longer than the input you expect, e.g. char buffer[1024]; and use them like the malloc buffers (of course don't free them) and see what difference this makes.
i have a c++ class that reads info about a file using stat. it sets dir and reg true on the respective files just fine but lnk remains false when i test it on a known sym link on my ubuntu PC ("/vmlinuz.old"). it sets reg true in this situation. must of my code is ref'ed here: http://linux.die.net/man/2/stat (stroll to the buttom)
class file_info
{
public:
string size;
string owner;
string group;
string path;
string acc_time;
string mod_time;
string cre_time;
bool read;
bool write;
bool exec;
bool dir;
bool lnk;
bool reg;
bool fail;
private:
struct stat f_stat;
void set_size()
{
string raw_size = to_string(f_stat.st_size);
unsigned int len = raw_size.size();
size = "";
if (len <= 3)
{
size += raw_size;
size += "Bytes";
return;
}
size += raw_size[len - 1];
size += ".";
size += raw_size[len - 2];
if ((len > 3) && (len < 6)) size += "KB";
else if ((len >= 6) && (len < 9)) size += "MB";
else if ((len >= 9) && (len < 12)) size += "GB";
else if ((len >= 12) && (len < 15)) size += "TB";
else if ((len >= 15) && (len < 18)) size += "PB";
else if ((len >= 18) && (len < 21)) size += "EB";
else size = "OL";
}
private:
void get_info()
{
switch (f_stat.st_mode & S_IFMT)
{
case S_IFDIR: dir = true; break;
case S_IFREG: reg = true; break;
case S_IFLNK: lnk = true; break;
default: fail = true; break;
}
if (!fail)
{
if (f_stat.st_mode & S_IRUSR) read = true;
if (f_stat.st_mode & S_IWUSR) write = true;
if (f_stat.st_mode & S_IXUSR) exec = true;
struct passwd *pw = getpwuid(f_stat.st_uid);
struct group *gr = getgrgid(f_stat.st_gid);
if (pw != NULL) owner = pw->pw_name;
if (gr != NULL) group = gr->gr_name;
set_size();
acc_time = ctime(&f_stat.st_atime);
mod_time = ctime(&f_stat.st_mtime);
cre_time = ctime(&f_stat.st_ctime);
acc_time.erase(acc_time.end() - 1, acc_time.end());
mod_time.erase(mod_time.end() - 1, mod_time.end());
cre_time.erase(cre_time.end() - 1, cre_time.end());
}
}
public:
file_info(string file): dir(false),
lnk(false),
reg(false),
fail(false),
read(false),
write(false),
exec(false)
{
path = file;
if (stat(file.c_str(), &f_stat))
{
fail = true;
}
else
{
get_info();
}
}
};
If I am not mistaken, you are using the stat() system call to check if a file is a symbolic link or not, using the S_IFLNK flag. Here is a quote from the man page:
stat() stats the file pointed to by path and fills in buf.
lstat() is identical to stat(), except that if path is a symbolic link,
then the link itself is stat-ed, not the file that it refers to.
Try using lstat() instead of stat(). stat() follows the link, and returns that the file the link links to is indeed a directory or regular file.
stat() returns information about the file to which a symbol link points... try lstat()