• Почему в windows адреса называются "виртуальными"?

    @sddvxd Автор вопроса
    Извиняюсь за дезинформацию. Адреса изначально представлены виртуальными, физический же адрес вычисляются по-разному в различных моделях представления виртуальной памяти
    Ответ написан
    Комментировать
  • Как ограничить FPS в OpenGL и glut?

    @sddvxd
    Если нужно 60 FPS, то получить текущее время, секунду поделить на 60 и каждые 1/60 секунды обновлять кадр
    Ответ написан
    Комментировать
  • Как экранировать символ в строке?

    @sddvxd Автор вопроса
    Мне тут уже подсказывали, забыл, что можно так:

    dll EQU `a\'`
    Ответ написан
    1 комментарий
  • Почему dword сохраняется в обратном порядке?

    @sddvxd Автор вопроса
    Ошибочка вышла: memory editor специально переводил блоки по 4 байта в удобочитаемый вид (big-endian). Если же сделать вывод по 1 байту, то все встает на свои места
    Ответ написан
    Комментировать
  • Как сделать такую ловушку?

    @sddvxd
    Я бы так сделал: сделал бы программу, которая внедряется в процесс, который создает процессы (например explorer.exe), в разделе импорта функции создания процессов поменял бы на свой и перехватывал создание процессов. При перехвате создания процесса вызывать оригинальный CreateProcess и запоминать дескриптор процесса. В только что созданный процесс внедрить dll для обработки опять же только что установленной ловушки на функцию открытия файла. Если filename == path_to_file/passwords.txt тогда самоуничтожение процесса

    PROC replaceProcAddress(LPCSTR callerModule, PROC original, PROC swap){
        HMODULE callerHandle = GetModuleHandleA(callerModule);
        if(callerHandle == nullptr)
            throw Exception(L"callerHandle is NULL in Process::replaceProcAddress");
    
        ULONG size;
        bool found = false;
        PIMAGE_IMPORT_DESCRIPTOR pImageDesc = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(ImageDirectoryEntryToData(callerHandle, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size));
        if(pImageDesc == nullptr)
            throw Exception(L"PIMAGE_IMPORT_DESCRIPTOR is NULL in Process::replaceProcAddress()");
    
        for(; pImageDesc->Name; pImageDesc++){
            PSTR pModName = reinterpret_cast<PSTR>(reinterpret_cast<PBYTE>(callerHandle) + pImageDesc->Name);
                PIMAGE_THUNK_DATA pThunkData = reinterpret_cast<PIMAGE_THUNK_DATA>(reinterpret_cast<PBYTE>(callerHandle) + pImageDesc->FirstThunk);
                for(; pThunkData->u1.Function; pThunkData++){
                    PROC* ppOriginalFunc = reinterpret_cast<PROC*>(&pThunkData->u1.Function);
                    if(*ppOriginalFunc == original){
                        found = true;
                        DWORD dwOldProtect;
                        if(VirtualProtect(ppOriginalFunc, sizeof(swap), PAGE_WRITECOPY, &dwOldProtect)){
                            if(!WriteProcessMemory(getHandle(), ppOriginalFunc, &swap, sizeof(swap), NULL))
                                throw Exception(L"Write memory is failed for replaceProcAddress");
                            VirtualProtect(ppOriginalFunc, sizeof(swap), dwOldProtect, &dwOldProtect);
                        }
                    }
                }
        }
        if(found) return swap;
        throw Exception(L"Address of procedure is not found in Process::replaceProcAddress()");
    }


    Это функция для смены адреса функции в разделе импорта на свой. Джеффри Рихтер
    Ответ написан
    Комментировать
  • По какому адресу запишется 1?

    @sddvxd Автор вопроса
    Кажется немного понял, поправьте пожалуйста, если не так - Если бы у меня был компьютер с big-endian, то единица записалась бы по адресу block + 3, не как я указал бы на mov dword [block], 1, а именно по адресу block + 3. В little endian записывалось именно так, как я бы указал. Видимо для этого и существует требование к уточнению размера операнда типа память, потому что порядок байтов бывает разный
    Ответ написан
  • Почему так записывается внешняя функция?

    @sddvxd Автор вопроса
    Ответ написан
    Комментировать
  • Как соединить программу на ассемблере с программой на C?

    @sddvxd Автор вопроса
    Проблема решена - я компилировал код не на C, а на C++ и редактор связей не мог найти символ. Проблема решилась добавлением extern "C" в код на C++
    Ответ написан
    Комментировать
  • Что такое *(float*)?

    @sddvxd
    Косвенное обращение к указателю, который приведен к типу float*

    В C++ принято использовать
    *reinterpet_cast<float*>()
    Ответ написан
    Комментировать
  • Как имитировать double click с помощью winapi?

    @sddvxd Автор вопроса
    INPUT input[2]{0};
    
        input[0].type = INPUT_MOUSE;
        input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    
        input[1].type = INPUT_MOUSE;
        input[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
    
        while(1){
            for(int i = 0; i < 2; ++i)
                SendInput(2, input, sizeof(INPUT));
            Sleep(1000);
        }
    Ответ написан
    Комментировать
  • Удалить все повторяющиеся элементы из массива?

    @sddvxd
    Советую познакомиться с новыми стандартами языка и стандартной библиотекой
    bool inArray(int* arr, int need, int count){
        for(int i = 0; i < count; ++i)
            if(arr[i] == need)
                return true;
    return false;
    }
    int* uniq(int* arr, int size, int& newSize){
        int* localArr = new int[size]{0};
        for(int i = 0; i < size; ++i){
            if(inArray(localArr - newSize, arr[i], size))
                continue;
            ++newSize;
            *localArr++ = arr[i];
        }
    return localArr - newSize;
    }
    
    int main(){
        int arr[10] = {1,2,3,4,2,4,5,6,7,4};
        int newSize = 0;
        int* newArr = uniq(arr, sizeof(arr)/sizeof(int), newSize);
        for(int i = 0; i < newSize; ++i)
            cout << newArr[i] << "\n";
    }
    Ответ написан
    6 комментариев
  • Что означает void функции в скобках с++?

    @sddvxd
    Явное указание того, что функция не имеет аргументов
    Ответ написан
    Комментировать
  • Как преобразовать char массив в int С++?

    @sddvxd
    Благодаря обсуждению первого ответа и ответов автора можно организовать следующую программу:
    union conv{
        char (*pcarr)[4];
        int* pint;
    };
    
    static conv bconv;
    
    int main(){
        bconv.pint = new int(100);
        cout << *((int*)bconv.pcarr) << "\n"; //int to char (*)[4]
    
        bconv.pcarr = (char(*)[4])new char[4]{1,2,3,4};
        cout << *bconv.pint << "\n"; //char (*)[4] to int
    }


    union conv{
        unsigned char (*pcarr)[4];
        int* vint;
    };
    
    static conv bconv;
    
    
    int main(){
        bconv.vint = new int(100);
        cout << *((int*)bconv.pcarr) << "\n"; //int to char (*)[4]
    
        bconv.pcarr = (unsigned char(*)[4])new unsigned char[4]{255,255,255,127}; //big-endian
        if(INT_MAX == *bconv.vint) cout << "bingo\n";
    }
    Ответ написан
    Комментировать
  • В чём может быть проблема Run-Time Check Failure #3?

    @sddvxd
    Там написано "x2 был использован без инициализации"
    Ответ написан
  • Возможно ли в С++ создать динамический класс-мимик, который может более одного раза "мимикрировать" под другой класс?

    @sddvxd
    class MimicBase{};
        class Vampire : public MimicBase{
        public:
            Vampire();
            Vampire(MimicBase& m) : MimicBase(m){};
        };
        class Elf : public MimicBase{
        public:
            Elf();
            Elf(MimicBase& m) : MimicBase(m){};
        };
    
        MimicBase m1;
        Vampire v1(m1);
        MimicBase m2(v1); //Обратно


    Суть в том, что при инициализации объекта класса, например, Vampire, вы берете под контроль вызов цепочки конструкторов и можете подставить объект родителя
    Ответ написан
    5 комментариев
  • C++ как заполнить вектор рандом?

    @sddvxd
    #include <iostream>
    #include <cstdio>
    #include <math.h>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        int* feel(const short&);
        int count = 20;
        int* pArrMain = feel(count);
        for(int i = 0; i < count; ++i){
            if(i % 10 == 0) cout << '\n';
            cout << pArrMain[i] << " ";
        }
    }
    
    int* feel(const short& count = 100){
        if(count <= 0) throw runtime_error("Bad size");
        int* pArr = new int[count];
        for(int i = 0; i < count; ++i)
            pArr[i] = rand() % 21;
        return pArr;
    }


    хм, у меня разные значения из рандом, может что-то поменяли и не нужно семя менять
    Ответ написан
    Комментировать
  • Как реализовать градиент серого цвета без использования графических библиотек (OpenCV и т.д.) на C/C++?

    @sddvxd
    Если вам действительно нужна идея, а не код готовой программы, вот вам моя мысль:

    int rows = 0, cols = 0;
        cout << "Enter size (Example: 200x200)\n";
        cin >> rows >> cols;
        if(rows <= 0 || cols <= 0) throw runtime_error("Bad size");
        int pixmap[rows][cols];
        for(int i = 0; i < rows; ++i){
            double position = double(i) / rows;   //Вычисляем "высоту"
            int color = position * 255;                 //и находим подходящий цвет
            cout << position << " " << color << '\n';
            for(int j = 0; j < cols; ++j)
                pixmap[i][j] = color;
        }


    FINAL VERSION:
    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    void main()
    {
        int rows = 0, cols = 0;
        char* filename = "test.pgm";
        cout << "Enter size and filename (Example: 200x200 mygradient.pgm)\n";
        cin >> rows >> cols >> filename;
        if(rows <= 0 || cols <= 0) throw runtime_error("Bad size");
        FILE* pfile = fopen(filename, "w");
        fprintf(pfile, "P2\n%d %d\n255\n", cols, rows);
        for(int i = 0; i < rows; ++i){
            double position = double(i) / rows;
            int color = position * 255;
            cout << position << " " << color << "\n";
            for(int j = 0; j < cols; ++j)
                fprintf(pfile, "%d ", color);
            fprintf(pfile, "\n");
        }
    }


    Вводить например вот так: 1500x400 file.pgm
    5bfb1d672efdc256620573.png
    Ответ написан
  • С++, Как решить такое на с++???

    @sddvxd
    #include <iostream>
    
    int main(){
      std::cout << "Enter the number: ";
      int number;
      std::cin >> number;
      int buffer = number;
      if(number <= 0) return 1;
      double multi_factor = 1;
      std::cout << std::endl;
      while((buffer = number * multi_factor) >= 1){
        std::cout << buffer << " ";
        multi_factor /= 2;
        if(buffer % 2 != 0) break;
      }
    
      std::cin.get();
      std::cin.get();
    
      return 0;
    }
    Ответ написан
    Комментировать
  • Почему первые 4 байта QString заняты?

    @sddvxd Автор вопроса
    Все, понял. bufferOut << pLineEdit->text(); возвращает объект QString, уже инициализированный строкой из QLineEdit, а значит у него уже стоит длина 12. Из-за своего малого опыта я думал, что мне вернется строка, но вернулся весь объект QString
    Ответ написан
    Комментировать
  • Когда вызывается сигнал "QTcpSocket::readyRead()"?

    @sddvxd Автор вопроса
    Решил свой вопрос. Просто поставил задержку между записью 2 секунды и начал отладку серверного приложения - сигнал QTcpSocket::readyRead() вызывается только при полном принятии байтов
    Ответ написан
    Комментировать