Другое С/С++ Вопрос - Ответ

Rolly666

Новичок
5
1
fQuaternion Hello i need help i want to know how to get my vehicle(vehicledata) on raknet to turn to the xyz i set to it, and also the code i send speed to the xyz i set to it and also the speed setting

And also forging my direction(aimdata)
 
Последнее редактирование:

san0

Известный
Друг
411
267
What is the best & safest way to clean std::string from memory ?
std::string example;
1. example.clear();
2. example.resize(0);
3. std::fill(example.begin(), example.end(), 0);
Hi there, such a cool question. Basically, have to distinguish what does "best & safest" mean in that context

By the rules of RTTI, standard definition of an object constructed in some arbitrary block (let's not include here some special cases like overloaded form of operator new()) will be destructed at the end of that block
C++:
{
    std::string my_string { "String!" };
    // ...
    // std::basic_string::~basic_string will be called
}

So you ain't gotta do that by yourself, no such need for neither .resize, nor free(), delete(), std::fill and others

In case 'safest method' stands for making sure data you operate within act must be zeroed / cleared, especially in cases when std::string will be used for storing sensitive data (passwords and others), well, there's no portable and unambiguous answer.

Doing manual .clear call does not give any guarantee that this call won't be optimized
Proof: https://godbolt.org/z/rdCQyQ

Same goes for the std::basic_string::~basic_string, it might or mightn't clear used memory

libc++, for example, does this

For a kick-off, there's has to be some function to do zeroing above some memory block with confidentially that this call/expression won't be optimized away by the compiler.
You might take a look at the following:

1) memset_s from C11. Even though it must be portable, there are some problems with C11 in, for instance, Visual Studio. Moreover, __STDC_WANT_LIB_EXT1__ and __STDC_WANT_LIB_EXT1__ must be used in any platform and there's another possible issue - MacOS might not work with those macroeses.

Код:
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>

// available to use function
// errno_t memset_s(void * restrict s, rsize_t smax, int c, rsize_t n)

2) write memset_s by yourself, don't miss volatile modifier
Код:
void zerofill(void *data, size_t size) {
    for (auto p = reinterpret_cast<volatile char*>(data); size; size--) {
      *(p + size) = 0;
    }
}

3) User platform-provided solutions

bzero on macOS doesn't have any rule for compiler optimizations, so skip that

SecureZeroMemory on Windows does exactly what needed


Secondly, there's a need to know what is the way zeroing might be perfomed

1) direct data access

Before c++17, you could give a try to &str[0], but it has undefined behavior when pos == size()

Since c++17, std::basic_string::data will return non const pointer if target string was not const

2) might try std::allocator by calling std::string::get_allocator, but it's sort of deprecated

To implement this like it should be in modern c++, you can try usual class inheritance, but i'd like to recommend do this with std::unique_ptr, since it has support for the disposal function
Of course, this doesn't cover cases you're dealing with classical OOP model and can do cleaning at your class destructor

Here are the tests i've done

C++:
#include <iostream>
#include <string>
#include <memory>
#include <functional>
#include <cstddef>
#include <utility>
#include <cstdint>

char* get_string_data(std::string& str) {
    if constexpr (!std::is_const<decltype(std::declval<std::string>().data())>())
        return str.data();
    else
        return &str[0];
}

namespace secure {
static void safe_clear(void *data, size_t size) {
    for (auto p = reinterpret_cast<volatile char*>(data); size; size--) {
      *(p + size) = 0;
    }
}
static void string_clear(std::string* str) {
    safe_clear(reinterpret_cast<void *>(get_string_data(*str)), str->capacity());
     str->~basic_string();
    ::operator delete(str);
}
}

struct dump {
    std::unique_ptr<uint8_t[]> buf;
    char* block;
    size_t block_size;

    dump(std::string& str) {
        block = get_string_data(str);
        block_size = str.capacity();
        buf = std::make_unique<uint8_t[]>(block_size);
        std::copy(block, block + block_size, buf.get());
    }
    
    static void print_block(const char* dd, size_t size) {
        for (const char* p = dd - size; p != dd; p++) {
            const auto c = *(p + size);
            std::cout << static_cast<int>(static_cast<unsigned char>(c)) << '(' << c << ')' << ' ';
        }
        std::cout << std::endl;
    }
};

template <char... c>
using str_seq = std::integer_sequence<char, c...>;

template <typename T, T... c>
constexpr str_seq<c...> operator""_s() {
    return { };
}

template <typename>
struct dump_var;

template <char... name_c>
struct dump_var<str_seq<name_c...>> {
    static constexpr char name[sizeof...(name_c) + 1] = { name_c..., '\0' };
    
    dump_var(std::function<dump (const char*)> f) {
        auto dumper = f(name);
        
        if (std::all_of(dumper.block, dumper.block+dumper.block_size, [](auto v){ return v == 0; }))
            std::cout << "Test {" << name << "} passed!" << std::endl;
        else {
            std::cout << "Test {" << name << "} NOT passed!" << std::endl;
            std::cout << "Memory block before" << std::endl;
            dump::print_block(reinterpret_cast<const char*>(dumper.buf.get()), dumper.block_size);
            std::cout << "Memory block after" << std::endl;
            dump::print_block(dumper.block, dumper.block_size);
        }
    }
};

auto main() -> int {
    dump_var<decltype("Normal std::string usage blah blah blah"_s)>(
    [](auto str) {
        std::string usual_way(str);
        usual_way.clear(); // <- going to be optimized
        return dump(usual_way);
    });

    dump_var<decltype("Custom deleter blah blah blah"_s)>(
    [](auto str) {
        std::unique_ptr<std::string, std::function<decltype(secure::string_clear)>> custom_deleter (
            new std::string(str),
            secure::string_clear
        );

        return dump(*custom_deleter);
    });
}

Код:
Test {Normal std::string usage blah blah blah} NOT passed!
Memory block before
0() 111(o) 114(r) 109(m) 97(a) 108(l) 32( ) 115(s) 116(t) 100(d) 58(:) 58(:) 115(s) 116(t) 114(r) 105(i) 110(n) 103(g) 32( ) 117(u) 115(s) 97(a) 103(g) 101(e) 32( ) 98(b) 108(l) 97(a) 104(h) 32( ) 98(b) 108(l) 97(a) 104(h) 32( ) 98(b) 108(l) 97(a) 104(h)
Memory block after
152(�) 43(+) 220(�) 249(�) 211(�) 127() 0() 0() 152(�) 43(+) 220(�) 249(�) 211(�) 127() 0() 0() 110(n) 103(g) 32( ) 117(u) 115(s) 97(a) 103(g) 101(e) 32( ) 98(b) 108(l) 97(a) 104(h) 32( ) 98(b) 108(l) 48(0) 0() 0() 0() 0() 0() 0()
Test {Custom deleter blah blah blah} passed!

Live: http://coliru.stacked-crooked.com/a/a08b5ab2257acbab

Think I described it in the way you needed, I mean I correctly represented a word "safest"

By the way, take a look how it's implemented in, for instance, chromium project
 

Carrentine

Потрачен
569
460
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Как узнать ID аттач процесса ?
C++:
DWORD GetProcId(const char* procname)
{
    PROCESSENTRY32 pe;
    HANDLE hSnap;

    pe.dwSize = sizeof(PROCESSENTRY32);
    hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    if (Process32First(hSnap, &pe)) {
        do {
            if (strcmp(pe.szExeFile, procname) == 0)
                break;
        } while (Process32Next(hSnap, &pe));
    }
    return pe.th32ProcessID;
}

/* By CleanLegend */
 

mrdiimax

Известный
566
79
C++:
DWORD GetProcId(const char* procname)
{
    PROCESSENTRY32 pe;
    HANDLE hSnap;

    pe.dwSize = sizeof(PROCESSENTRY32);
    hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
    if (Process32First(hSnap, &pe)) {
        do {
            if (strcmp(pe.szExeFile, procname) == 0)
                break;
        } while (Process32Next(hSnap, &pe));
    }
    return pe.th32ProcessID;
}

/* By CleanLegend */
46390
 

Vintik

Мечтатель
Проверенный
1,471
920
Если ты открываешь чат с помощью имитации нажатия клавиши, в чем проблема с помощью имитаций напечатать текст?
проблема в том, что у меня может не быть нужной раскладки на пк (например, нету русской, а текст русскими буквами)
 

Vintik

Мечтатель
Проверенный
1,471
920
Разве раскладку нельзя русскую поставить?)
Я задал другой вопрос, я понимаю, что можно извращаться как угодно.
Мой вопрос звучит так: можно ли имитировать ввод символа (даже если на твоей раскладке нету такого)? если да, то как это сделать.
 

Бубликов И.И

Потрачен
37
13
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Последнее редактирование модератором:
  • Нравится
Реакции: 4el0ve4ik