avcodec_encode_video2 the memory usage is very high - c

code:
```
#include "pch.h"
#include
extern "C"
{
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include <libavcodec/avcodec.h>
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavutil/avutil.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include <libavutil/rational.h>
//#include "libavutil/avassert.h"
//#include "libavutil/attributes.h"
//#include "libavutil/avassert.h"
//#include "libavutil/frame.h"
//#include "libavutil/imgutils.h"
//#include "internal1.h"
//#include "libavutil/samplefmt.h"
}
#include <vld.h>
//#include "avcodec.h"
//#include "frame_thread_encoder.h"
//#include "internal.h"
// Globals
AVCodec* m_pCodec = NULL;
AVStream *m_pStream = NULL;
AVOutputFormat* m_pFormat = NULL;
AVFormatContext* m_pFormatContext = NULL;
AVCodecContext* m_pCodecContext = NULL;
AVFrame* m_pFrame = NULL;
int m_frameIndex;
// Output format
AVPixelFormat m_pixType = AV_PIX_FMT_NV12;
// Use for mpeg4
//AVPixelFormat m_pixType = AV_PIX_FMT_YUV420P;
// Output frame rate
int m_frameRate = 30;
// Output image dimensions
int m_imageWidth = 256;
int m_imageHeight = 1537;
// Number of frames to export
int m_frameCount = 20000;
// Output file name
const char* m_fileName = "test.h264";
// Output file type
const char* m_fileType = "H264";
// Codec name used to encode
const char* m_encoderName = "h264_qsv";
// use for mpeg4
//const char* m_encoderName = "mpeg4";
// Target bit rate
int m_targetBitRate = 400000;
void addVideoStream()
{
m_pStream = avformat_new_stream(m_pFormatContext, m_pCodec);
m_pStream->id = m_pFormatContext->nb_streams - 1;
m_pStream->time_base = m_pCodecContext->time_base;
m_pStream->codec->pix_fmt = m_pixType;
m_pStream->codec->flags = m_pCodecContext->flags;
m_pStream->codec->width = m_pCodecContext->width;
m_pStream->codec->height = m_pCodecContext->height;
m_pStream->codec->time_base = m_pCodecContext->time_base;
m_pStream->codec->bit_rate = m_pCodecContext->bit_rate;
}
AVFrame* allocatePicture(enum AVPixelFormat pix_fmt, int width, int height)
{
AVFrame *frame;
frame = av_frame_alloc();
if (!frame)
{
return NULL;
}
frame->format = pix_fmt;
frame->width = width;
frame->height = height;
int checkImage = av_image_alloc(frame->data, frame->linesize, width, height, pix_fmt, 32);
if (checkImage < 0)
{
return NULL;
}
return frame;
}
bool initialize()
{
AVRational frameRate;
frameRate.den = m_frameRate;
frameRate.num = 1;
av_register_all();
m_pCodec = avcodec_find_encoder_by_name(m_encoderName);
if (!m_pCodec)
{
return false;
}
m_pCodecContext = avcodec_alloc_context3(m_pCodec);
m_pCodecContext->width = m_imageWidth;
m_pCodecContext->height = m_imageHeight;
m_pCodecContext->time_base = frameRate;
m_pCodecContext->gop_size = 0;
m_pCodecContext->pix_fmt = m_pixType;
m_pCodecContext->codec_id = m_pCodec->id;
m_pCodecContext->bit_rate = m_targetBitRate;
av_opt_set(m_pCodecContext->priv_data, "+CBR", "", 0);
return true;
}
bool startExport()
{
m_frameIndex = 0;
char fakeFileName[512];
int checkAllocContext = avformat_alloc_output_context2(&m_pFormatContext, NULL, m_fileType, fakeFileName);
if (checkAllocContext < 0)
{
return false;
}
if (!m_pFormatContext)
{
return false;
}
m_pFormat = m_pFormatContext->oformat;
if (m_pFormat->video_codec != AV_CODEC_ID_NONE)
{
addVideoStream();
int checkOpen = avcodec_open2(m_pCodecContext, m_pCodec, NULL);
if (checkOpen < 0)
{
return false;
}
m_pFrame = allocatePicture(m_pCodecContext->pix_fmt, m_pCodecContext->width, m_pCodecContext->height);
if (!m_pFrame)
{
return false;
}
m_pFrame->pts = 0;
}
int checkOpen = avio_open(&m_pFormatContext->pb, m_fileName, AVIO_FLAG_WRITE);
if (checkOpen < 0)
{
return false;
}
av_dict_set(&(m_pFormatContext->metadata), "title", "QS Test", 0);
int checkHeader = avformat_write_header(m_pFormatContext, NULL);
if (checkHeader < 0)
{
return false;
}
return true;
}
int processFrame(AVPacket& avPacket)
{
avPacket.stream_index = 0;
avPacket.pts = av_rescale_q(m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base);
avPacket.dts = av_rescale_q(m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base);
m_pFrame->pts++;
int retVal = av_interleaved_write_frame(m_pFormatContext, &avPacket);
return retVal;
}
bool exportFrame()
{
int success = 1;
int result = 0;
AVPacket avPacket;
av_init_packet(&avPacket);
avPacket.data = NULL;
avPacket.size = 0;
AVPacket* avPacket1 = new AVPacket();
av_init_packet(avPacket1);
avPacket1->data = NULL;
avPacket1->size = 0;
fflush(stdout);
std::cout << "Before avcodec_encode_video2 for frame: " << m_frameIndex << std::endl;
success = avcodec_encode_video2(m_pCodecContext, &avPacket, m_pFrame, &result);
std::cout << "After avcodec_encode_video2 for frame: " << m_frameIndex << std::endl;
if (result)
{
success = processFrame(avPacket);
}
av_packet_unref(&avPacket);
av_free_packet(&avPacket);
//av_frame_free(&m_pFrame);
m_frameIndex++;
return (success == 0);
}
void endExport()
{
int result = 0;
int success = 0;
if (m_pFrame)
{
while (success == 0)
{
AVPacket avPacket;
av_init_packet(&avPacket);
avPacket.data = NULL;
avPacket.size = 0;
fflush(stdout);
success = avcodec_encode_video2(m_pCodecContext, &avPacket, NULL, &result);
if (result)
{
success = processFrame(avPacket);
}
av_packet_unref(&avPacket);
if (!result)
{
break;
}
}
}
if (m_pFormatContext)
{
av_write_trailer(m_pFormatContext);
if (m_pFrame)
{
av_frame_free(&m_pFrame);
}
avio_closep(&m_pFormatContext->pb);
avformat_free_context(m_pFormatContext);
m_pFormatContext = NULL;
}
}
void cleanup()
{
if (m_pFrame || m_pCodecContext)
{
if (m_pFrame)
{
av_frame_free(&m_pFrame);
}
if (m_pCodecContext)
{
avcodec_close(m_pCodecContext);
av_free(m_pCodecContext);
}
}
}
int main()
{
bool success = true;
if (initialize())
{
if (startExport())
{
for (int loop = 0; loop < m_frameCount; loop++)
{
if (!exportFrame())
{
std::cout << "Failed to export frame\n";
success = false;
break;
}
}
endExport();
}
else
{
std::cout << "Failed to start export\n";
success = false;
}
cleanup();
}
else
{
std::cout << "Failed to initialize export\n";
success = false;
}
if (success)
{
std::cout << "Successfully exported file\n";
}
return 1;
}
```
When I set the m_imageHeight to 1536, the memory usage is very high. But when set to 1535 or 1537 or other values, the memory usage is normal, can you tell me why?
I have navigated to avcodec_encode_video2
enter link description here
I am using the code from the link
I have updated to the latest Intel® Graphics Driver

Related

Static struct initialization

I'm having issues with initializing certain structs which are declared as static in my library header
Header file:
struct game_setting
{
uint8_t parameter;
uint8_t alternatives[6];
uint8_t alternatives_number;
};
static game_setting game_status;
init-function in .c-file:
void menu_init()
{
static uint8_t game_parameters_array[6];
static game_setting game_status = {&game_parameters_array[RUN_STATUS],{OFF,ON},2}
Which returns 'Initializer element is not computable at load time'
I'm looking for an efficient way of assigning values to the static struct, what is wrong?
Main script
#define F_CPU 4915200UL
#define OFFSET 0x2000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
#include "SPI.h"
#include "MCP2515.h"
#include "MCP2515_Commands.h"
#include "adc.h"
#include "multiboard.h"
#include "OLED.h"
#include "OLED_menu.h"
#include "CAN.h"
#include "USART.h"
#define SPI_DEBUG
#define CAN_MESSAGE_DEBUG
#define UPDATEMESSAGES 255
// Define baud rate
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
int main(void){
FILE fileHandle = USART_Init();
init_xMem();
stdout = &fileHandle;
stdin = &fileHandle;
printf("start of init\n\r");
menu_init();
printf("menu_init completed\n");
OLED_init();
CAN_init();
ADCInit();
initController();
can_message msg;
msg.id = 1;
controller C;
int i = 1;
while (1) {
menu_page_print_data();
_delay_ms(1000);
}
}
Full OLED_menu .c-file (relevant functions works without OLED.h definitions):
#include "OLED.h"
#include "OLED_menu.h"
void menu_init()
{
menu_page_address_offset = 0x1C01;
game_setting_address_offset = 0x1F01;
game_status = game_setting_address_offset;
game_setting_address_offset += 1;
uint8_t alternatives[6];
game_status->parameter = &game_parameters_array[RUN_STATUS];
game_status->alternatives[0] = OFF;
game_status->alternatives[1] = ON;
game_status->alternatives_number = 2;
start_game = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&start_game->title, "Start game");
start_game->submenu_pages[0] = NULL;
start_game->parent_menu_page = main_menu;
start_game->submenu_pages_number = 0;
start_game->setting = &game_status;
solenoid_param = game_setting_address_offset;
game_setting_address_offset += 1;
solenoid_param->parameter = &game_parameters_array[SOLENOID];
solenoid_param->alternatives[0] = X_POSITION;
solenoid_param->alternatives[1] = Y_POSITION;
solenoid_param->alternatives[2] = LEFT_SLIDER;
solenoid_param->alternatives[3] = RIGHT_SLIDER;
solenoid_param->alternatives_number = 4;
solenoid_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&solenoid_control->title,"Solenoid");
solenoid_control->submenu_pages[0] = NULL;
solenoid_control->parent_menu_page = NULL;
solenoid_control->submenu_pages_number = 0;
solenoid_control->setting = &solenoid_param;
servo_param = game_setting_address_offset;
game_setting_address_offset += 1;
servo_param->parameter = &game_parameters_array[SERVO];
servo_param->alternatives[0] = X_POSITION;
servo_param->alternatives[1] = Y_POSITION;
servo_param->alternatives[2] = LEFT_SLIDER;
servo_param->alternatives[3] = RIGHT_SLIDER;
servo_param->alternatives_number = 4;
servo_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&servo_control->title, "Servo");
servo_control->submenu_pages[0] = NULL;
servo_control->parent_menu_page = NULL;
servo_control->submenu_pages_number = 0;
servo_control->setting = &servo_param;
motor_param = game_setting_address_offset;
game_setting_address_offset += 1;
motor_param->parameter = &game_parameters_array[MOTOR];
motor_param->alternatives[0] = X_POSITION;
motor_param->alternatives[1] = Y_POSITION;
motor_param->alternatives[2] = LEFT_SLIDER;
motor_param->alternatives[3] = RIGHT_SLIDER;
motor_control = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(&motor_control->title, "Motor");
motor_control->submenu_pages[0] = NULL;
motor_control->parent_menu_page = NULL;
motor_control->submenu_pages_number = 0;
motor_control->setting = &motor_param;
controller_layout = menu_page_address_offset;
//printf("Controller_layout addr: , %d\n", (int)menu_page_address_offset);
menu_page_address_offset += 1;
/*
strcpy(controller_layout->title, "Controller Layout");
controller_layout->submenu_pages[0] = motor_control;
printf("motor_control : %X\n", motor_control);
controller_layout->submenu_pages[1] = servo_control;
controller_layout->submenu_pages[2] = solenoid_control;
controller_layout->parent_menu_page = NULL;
controller_layout->submenu_pages_number = 3;
controller_layout->setting = NULL;
settings_advanced = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(settings_advanced->title, "Advanced Settings");
settings_advanced->submenu_pages[0] = NULL;
settings_advanced->parent_menu_page = NULL;
settings_advanced->submenu_pages_number = 0;
settings_advanced->setting = NULL;
difficulty_param->parameter = &game_parameters_array[DIFFICULTY];
difficulty_param->alternatives[0] = DIFFICULTY_EASY;
difficulty_param->alternatives[1] = DIFFICULTY_NORMAL;
difficulty_param->alternatives[2] = DIFFICULTY_HARD;
difficulty_param->alternatives_number = 3;
settings_difficulty = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(settings_difficulty->title, "Difficulty");
settings_difficulty->submenu_pages[0] = NULL;
settings_difficulty->parent_menu_page = NULL;
settings_difficulty->submenu_pages_number = 0;
settings_difficulty->setting = &difficulty_param;
menu_setting = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(menu_setting->title, "Settings");
menu_setting->submenu_pages[0] = controller_layout;
menu_setting->submenu_pages[1] = settings_difficulty;
menu_setting->submenu_pages[2] = settings_advanced;
//printf("Child 1 before: %d, %d",menu_setting->submenu_pages[0], controller_layout);
menu_setting->parent_menu_page = NULL;
menu_setting->submenu_pages_number = 3;
menu_setting->setting = NULL;
*/
menu_setting = menu_page_address_offset;
menu_page_address_offset += 1;
main_menu = menu_page_address_offset;
menu_page_address_offset += 1;
strcpy(main_menu->title, "Main Menu");
main_menu->submenu_pages[0] = start_game;
main_menu->submenu_pages[1] = menu_setting;
main_menu->parent_menu_page = NULL;
main_menu->submenu_pages_number = 2;
main_menu->setting = NULL;
menu_assign_parents(&main_menu);
}
void game_setting_init(game_setting* setting, uint8_t* parameter, uint8_t* alternatives, uint8_t elements)
{
setting->parameter = parameter;
for (int i; i < elements; i++)
{
setting->alternatives[i] = alternatives[i];
}
}
int menu_assign_parents(menu_page* parent)
{
if(parent->submenu_pages_number > 6)
{
return -1;
}
for (int i; i < parent->submenu_pages_number; i++)
{
parent->submenu_pages[i]->parent_menu_page = parent;
if(menu_assign_parents(parent->submenu_pages[i]) == -1)
{
return -1;
}
}
return 0;
}
int menu_page_print(menu_page* page)
{
OLED_SRAM_Position_reset();
OLED_TextBox_clear((boundary) {0,127,0,7});
OLED_Goto_position(0,40);
//printf("%d parent, ", page->submenu_pages_number);
OLED_String_print(page->title, FONT_LARGE);
for (int i = 0; i < page->submenu_pages_number; i++)
{
OLED_Goto_position(i+1,5);
OLED_String_print(page->submenu_pages[i]->title, FONT_NORMAL);
//printf("%s\n", page->submenu_pages[i].title);
}
return 0;
}
menu_page* menu_page_select(menu_page* page,controller* C)
{
menu_page_print(page);
if(page->submenu_pages_number <= 0)
{
return (menu_page*)-1;
}
int submenu_number = -1;
int submenu_result = -1;
controller_direction generalDirection_prev;
while(!C->rightButton)
{
updateController(C);
if(generalDirection_prev != C->J.generalDirection)
{
switch(C->J.generalDirection)
{
case (DOWN):
submenu_number = (submenu_number + 1)%page->submenu_pages_number;
break;
case (UP):
submenu_number--;
if(submenu_number < 0)
{
submenu_number = page->submenu_pages_number-1;
}
break;
}
menu_page_selection_mark(submenu_number+1, page);
generalDirection_prev = C->J.generalDirection;
}
}
return &(page->submenu_pages[submenu_number]);
}
int TextBox_init(OLED_TextBox** box, char* str, TextBox_pos position, uint8_t line)
{
uint8_t StringLength = strlen(str);
printf("%d\n\r", StringLength);
if (118 / StringLength >= FONT_LARGE)
{
(*box)->FontSize = FONT_LARGE;
}
else if (118 / StringLength >= FONT_NORMAL)
{
(*box)->FontSize = FONT_NORMAL;
}
else if (118 / StringLength >= FONT_SMALL)
{
(*box)->FontSize = FONT_SMALL;
}
printf("%d\n\r", (*box)->FontSize);
switch (position)
{
case TEXBOX_LEFT:
(*box)->Boundaries = (boundary){5,5+StringLength*(*box)->FontSize,line,line};
case TEXTBOX_CENTER:
printf("%d\n\r", (128-(*box)->FontSize*StringLength)/2);
(*box)->Boundaries = (boundary){(128-(*box)->FontSize*StringLength)/2, (128+StringLength*(*box)->FontSize+1)/2,line,line};
printf("%d, %d, %d, %d nr1\n\r", (*box)->Boundaries.Left, (*box)->Boundaries.Right, (*box)->Boundaries.Top, (*box)->Boundaries.Bottom);
//printf("%d\n\r", (*box)->FontSize);
case TEXTBOX_RIGHT:
(*box)->Boundaries =(boundary){128-5-StringLength*(*box)->FontSize, 128-5,line,line};
}
(*box)->string = str;
return 0;
}
int menu_page_selection_mark(uint8_t rowIndex, menu_page* menu)
{
if(rowIndex < 1)
{
return -1;
}
//printf("Current index: %s\n", menu->submenu_pages[rowIndex].title);
static int rowIndex_prev = -1;
if(rowIndex_prev > -1)
{
OLED_Clear_line(rowIndex_prev);
OLED_Goto_position(rowIndex_prev, 5);
printf("title: %s\n", menu->submenu_pages[rowIndex_prev-1]->title);
OLED_String_print(menu->submenu_pages[rowIndex_prev-1]->title, FONT_LARGE);
}
OLED_Clear_line(rowIndex);
OLED_Goto_position(rowIndex, 7);
OLED_String_print(menu->submenu_pages[rowIndex-1]->title, FONT_LARGE);
OLED_String_print(" <-", FONT_LARGE);
rowIndex_prev = rowIndex;
return rowIndex;
}
void menu_page_print_data()
{
menu_page* page = main_menu;
printf("Menu page %s: Children: ", page->title);
for (int i; i < page->submenu_pages_number; i++)
{
printf("%s ", page->submenu_pages[i]->title);
}
printf("Parent: %s", page->parent_menu_page->title);
}
int menu_print_parameters(game_setting* settings, controller* C)
{
static uint8_t current_position = 1;
controller_direction generalDirection_prev;
menu_print_parameter_line(settings, LEFT, current_position);
while(!C->leftButton)
{
if(C->J.generalDirection != generalDirection_prev)
{
if (C->J.generalDirection == LEFT)
{
current_position = menu_print_parameter_line(settings, LEFT, current_position);
}
else if(C->J.generalDirection == RIGHT)
{
current_position = menu_print_parameter_line(settings, RIGHT, current_position);
}
}
}
}
int menu_print_parameter_line(game_setting* setting, controller_direction direction, uint8_t position)
{
char* string;
uint8_t next_position;
if(setting->alternatives_number == 0)
{
return -1;
}
if(direction == LEFT)
{
next_position = position -1;
}
else if(direction == RIGHT)
{
next_position = position +1;
}
OLED_Clear_line(6);
OLED_Goto_position(6,127);
OLED_String_print("<-", FONT_LARGE);
sprintf(&string, setting->alternatives[next_position]);
OLED_String_print(string, FONT_LARGE);
OLED_String_print("->", FONT_LARGE);
return next_position;
}
int menu_assign_parameters(menu_page* page, controller* C)
{
}
int menu_run(menu_page* page, controller* C)
{
menu_page* next_submenu_page;
menu_page* current_page = page;
while(next_submenu_page != -1)
{
current_page = next_submenu_page;
next_submenu_page = menu_page_select(current_page, C);
}
}
OLED_menu.h-file:
#ifndef OLED_MENU_H
#define OLED_MENU_H
#include "symbols_enums.h"
#include "OLED.h"
#include "multiboard.h"
#include "CAN_message_IDs.h"
#include <assert.h>
#include <string.h>
#include <avr/delay.h>
typedef struct menu_page menu_page;
typedef struct game_setting game_setting;
struct game_setting
{
uint8_t* parameter;
uint8_t alternatives[6];
uint8_t alternatives_number;
};
struct menu_page
{
char title[12];
menu_page* submenu_pages[4];
menu_page* parent_menu_page;
uint8_t submenu_pages_number;
//Used to set values for settings:
game_setting* setting;
};
typedef enum {TEXBOX_LEFT, TEXTBOX_CENTER, TEXTBOX_RIGHT}TextBox_pos;
static volatile menu_page* menu_page_address_offset;
static volatile game_setting* game_setting_address_offset;
static uint8_t game_parameters_array[5];
//Indicates if the game should start/stop:
static volatile game_setting* game_status;
static volatile menu_page* start_game;
//***********************************
static volatile game_setting* solenoid_param;
static volatile menu_page* solenoid_control;
static volatile game_setting* servo_param;
static volatile menu_page* servo_control;
static volatile game_setting* motor_param;
static volatile menu_page* motor_control; //Controller layout
//***********************************
static volatile menu_page* controller_layout;
static volatile menu_page* settings_advanced;
static volatile game_setting* difficulty_param;
static volatile menu_page* settings_difficulty;
static volatile menu_page* menu_setting;
static volatile menu_page* main_menu;
int menu_page_init(char*, menu_page*, menu_page*);
int menu_page_print(menu_page* page);
menu_page* menu_page_select(menu_page* page,controller* C);
int menu_page_selection_mark(uint8_t, menu_page*);
void menu_page_print_data();
int menu_print_parameter_line(game_setting*, controller_direction , uint8_t);
//int TextBox_init(OLED_TextBox**, char*, TextBox_pos, uint8_t);
#endif // OLED_MENU_H
I changed it to manually initialize one struct member at a time, which seems to work. However, when executing the program crashes before the menu_init() finishes due to these initializations:
menu_setting->submenu_pages[0] = controller_layout;
menu_setting->submenu_pages[1] = settings_difficulty;
menu_setting->submenu_pages[2] = settings_advanced;
main_menu->submenu_pages[0] = start_game;
main_menu->submenu_pages[1] = menu_setting;
controller_layout->submenu_pages[1] = servo_control;
controller_layout->submenu_pages[2] = solenoid_control
The initialization is providing the address of a thing, not the thing itself.
struct game_setting {
uint8_t parameter; // this is a byte
...
};
then in main()
{
static uint8_t game_parameters_array[6];
static struct game_setting game_status = {
&game_parameters_array[RUN_STATUS], // this is an address, not a byte
...
}
Also, I didn't see the definition of RUN_STATUS - is there any chance it's not a constant value? If it's a macro for something that can change (like a status flag), then it's not something suitable for indexing at load time to initialize this.

Driver Blue Screen of Death System Service Exception

I'm Trying to test this Sagaan AntiCheat but i got bluescreen i use OSRLoader to load the driver and its load perfectly but when i open the .exe it's give me Blue Screen of Death https://prnt.sc/m9zl6o
the Source code of the FullProject https://github.com/SagaanTheEpic/Sagaan-AntiCheat-V2.0 I cant see where is the error can someone help me analyze this project that im trying to build. i want to recode it to add more features and make it better more.
#include <ntdef.h>
#include <ntifs.h>
#include <ntddk.h>
#include <ntdddisk.h>
#include <scsi.h>
#include <ntddscsi.h>
#include <mountdev.h>
#include <mountmgr.h>
#include <stdio.h>
#include <ntifs.h>
#include <ntddk.h>
#include <windef.h>
#include <wdf.h>
#include <ntdef.h>
#include "BlackBone\VadRoutines.h"
#include "BlackBone\Routines.h"
#include "DriverIO.h"
#include "Formula.h"
DRIVER_INITIALIZE DriverEntry;
#pragma alloc_text(INIT, DriverEntry)
#define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
#define SYSTEM_PROCESS_ID (HANDLE)4
PVOID ObHandle = NULL;
ULONG ProtectedProcess = 0;
ULONG UsermodeAntiCheat = 0;
ULONG ProtectionThreads[7];
VOID CreateThreadNotifyRoutine(
IN HANDLE ProcessId,
IN HANDLE ThreadId,
IN BOOLEAN Create
);
// Terminating a process of your choice using the PID, usefull if the cheat is also using a driver to strip it's handles and therefore you can forcefully close it using the driver
NTSTATUS TerminateProcess(ULONG targetPid)
{
if (targetPid == ProtectedProcess)
{
ProtectedProcess = 0;
}
if (targetPid == UsermodeAntiCheat)
{
UsermodeAntiCheat = 0;
}
NTSTATUS NtRet = ((NTSTATUS)0x00000000L);
PEPROCESS PeProc = { 0 };
NtRet = PsLookupProcessByProcessId(targetPid, &PeProc);
if (NtRet != ((NTSTATUS)0x00000000L))
{
return NtRet;
}
HANDLE ProcessHandle;
NtRet = ObOpenObjectByPointer(PeProc, NULL, NULL, 25, *PsProcessType, KernelMode, &ProcessHandle);
if (NtRet != ((NTSTATUS)0x00000000L))
{
return NtRet;
}
ZwTerminateProcess(ProcessHandle, 0);
ZwClose(ProcessHandle);
return NtRet;
}
NTSTATUS DriverDispatchRoutine(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
PVOID buffer;
NTSTATUS NtStatus = STATUS_SUCCESS;
PIO_STACK_LOCATION pIo;
pIo = IoGetCurrentIrpStackLocation(pIrp);
pIrp->IoStatus.Information = 0;
switch (pIo->MajorFunction)
{
case IRP_MJ_CREATE:
NtStatus = STATUS_SUCCESS;
break;
case IRP_MJ_READ:
NtStatus = STATUS_SUCCESS;
break;
case IRP_MJ_WRITE:
break;
case IRP_MJ_CLOSE:
NtStatus = STATUS_SUCCESS;
break;
default:
NtStatus = STATUS_INVALID_DEVICE_REQUEST;
break;
}
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return NtStatus;
}
// This will be called, if the driver is unloaded or just returns something
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
DbgPrintEx(0, 0, "UNLOADED \n");
UNICODE_STRING SACSymbolName;
RtlInitUnicodeString(&SACSymbolName, L"\\DosDevices\\SACDriver"); // Giving the driver a symbol
if (ObHandle)
{
ObUnRegisterCallbacks(ObHandle);
ObHandle = NULL;
}
PsRemoveCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
IoDeleteSymbolicLink(&SACSymbolName);
IoDeleteDevice(pDriverObject->DeviceObject);
}
NTSTATUS Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
extern NTSTATUS PsLookupProcessByProcessId(
HANDLE ProcessId,
PEPROCESS *Process
);
typedef struct _OB_REG_CONTEXT {
USHORT Version;
UNICODE_STRING Altitude;
USHORT ulIndex;
OB_OPERATION_REGISTRATION *OperationRegistration;
} REG_CONTEXT, *PREG_CONTEXT;
OB_PREOP_CALLBACK_STATUS ThreadPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
UNREFERENCED_PARAMETER(RegistrationContext);
if (OperationInformation->KernelHandle)
return OB_PREOP_SUCCESS;
if ((ULONG)PsGetCurrentProcessId() == UsermodeAntiCheat)
{
return OB_PREOP_SUCCESS;
}
if ((ULONG)PsGetCurrentProcessId() == ProtectedProcess)
{
return OB_PREOP_SUCCESS;
}
if (PsGetThreadProcessId(OperationInformation->Object) == UsermodeAntiCheat)
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);
else
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);
}
else if (PsGetThreadProcessId(OperationInformation->Object) == ProtectedProcess)
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);
else
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE | THREAD_QUERY_LIMITED_INFORMATION);
}
return OB_PREOP_SUCCESS;
}
OB_PREOP_CALLBACK_STATUS ProcessPreCallback(PVOID RegistrationContext, POB_PRE_OPERATION_INFORMATION OperationInformation)
{
UNREFERENCED_PARAMETER(RegistrationContext);
if (UsermodeAntiCheat == 0)
return OB_PREOP_SUCCESS;
if (ProtectedProcess == 0)
return OB_PREOP_SUCCESS;
PEPROCESS ProtectedProcessPEPROCESS;
PEPROCESS ProtectedUserModeACPEPROCESS;
PEPROCESS OpenedProcess = (PEPROCESS)OperationInformation->Object,
CurrentProcess = PsGetCurrentProcess();
ULONG ulProcessId = PsGetProcessId(OpenedProcess);
PsLookupProcessByProcessId(ProtectedProcess, &ProtectedProcessPEPROCESS);
PsLookupProcessByProcessId(ProtectedProcess, &ProtectedUserModeACPEPROCESS);
if (OperationInformation->KernelHandle)
return OB_PREOP_SUCCESS;
if (ProtectedProcess != 0)
{
if (PsGetProcessId((PEPROCESS)OperationInformation->Object) == ProtectedProcess)
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) // striping handle
{
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE);
}
else
{
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE);
}
return OB_PREOP_SUCCESS;
}
}
if (UsermodeAntiCheat != 0)
{
if (PsGetProcessId((PEPROCESS)OperationInformation->Object) == UsermodeAntiCheat)
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE) // striping handle
{
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = (SYNCHRONIZE);
}
else
{
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = (SYNCHRONIZE);
}
return OB_PREOP_SUCCESS;
}
}
return OB_PREOP_SUCCESS;
}
VOID CreateThreadNotifyRoutine(
IN HANDLE ProcessId,
IN HANDLE ThreadId,
IN BOOLEAN Create
)
{
if (!Create)
{
if (UsermodeAntiCheat == ProcessId)
{
for (int x = 0; x > 8; x++)
{
if ((ULONG)ThreadId == ProtectionThreads[x])
{
TerminateProcess(ProtectedProcess);
TerminateProcess(UsermodeAntiCheat);
}
}
}
if (ProtectedProcess == ProcessId)
{
}
}
}
VOID EnableCallBack()
{
NTSTATUS NtHandleCallback = STATUS_UNSUCCESSFUL;
NTSTATUS NtThreadCallback = STATUS_UNSUCCESSFUL;
OB_OPERATION_REGISTRATION OBOperationRegistration[2];
OB_CALLBACK_REGISTRATION OBOCallbackRegistration;
REG_CONTEXT regContext;
UNICODE_STRING usAltitude;
memset(&OBOperationRegistration, 0, sizeof(OB_OPERATION_REGISTRATION));
memset(&OBOCallbackRegistration, 0, sizeof(OB_CALLBACK_REGISTRATION));
memset(&regContext, 0, sizeof(REG_CONTEXT));
regContext.ulIndex = 1;
regContext.Version = 120;
RtlInitUnicodeString(&usAltitude, L"1000");
if ((USHORT)ObGetFilterVersion() == OB_FLT_REGISTRATION_VERSION)
{
//OBOperationRegistration.ObjectType = PsProcessType; // Use To Strip Handle Permissions For Threads PsThreadType
//OBOperationRegistration.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
//OBOperationRegistration.PostOperation = PostCallBack; // Giving the function which happens after creating
//OBOperationRegistration.PreOperation = PreCallback; // Giving the function which happens before creating
OBOperationRegistration[1].ObjectType = PsProcessType;
OBOperationRegistration[1].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
OBOperationRegistration[1].PreOperation = ProcessPreCallback;
OBOperationRegistration[1].PostOperation = NULL;
OBOperationRegistration[0].ObjectType = PsThreadType;
OBOperationRegistration[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
OBOperationRegistration[0].PreOperation = ThreadPreCallback;
OBOperationRegistration[0].PostOperation = NULL;
OBOCallbackRegistration.Version = OB_FLT_REGISTRATION_VERSION;
OBOCallbackRegistration.OperationRegistrationCount = 2;
OBOCallbackRegistration.RegistrationContext = NULL;
OBOCallbackRegistration.OperationRegistration = &OBOperationRegistration;
NtHandleCallback = ObRegisterCallbacks(&OBOCallbackRegistration, &ObHandle); // Register The CallBack
PsSetCreateThreadNotifyRoutine(CreateThreadNotifyRoutine);
if (!NT_SUCCESS(NtHandleCallback))
{
if (ObHandle)
{
ObUnRegisterCallbacks(ObHandle);
ObHandle = NULL;
}
DbgPrintEx(0, 0, "Error: ObRegisterCallbacks Has Failed\n");
}
else
{
}
}
}
static ULONG KsecRandomSeed = 0x62b409a1;
NTSTATUS
NTAPI
KsecGenRandom(
PVOID Buffer,
SIZE_T Length)
{
LARGE_INTEGER TickCount;
ULONG i, RandomValue;
PULONG P;
/* Try to generate a more random seed */
KeQueryTickCount(&TickCount);
KsecRandomSeed ^= _rotl(TickCount.LowPart, (KsecRandomSeed % 23));
P = Buffer;
for (i = 0; i < Length / sizeof(ULONG); i++)
{
P[i] = RtlRandomEx(&KsecRandomSeed);
}
Length &= (sizeof(ULONG) - 1);
if (Length > 0)
{
RandomValue = RtlRandomEx(&KsecRandomSeed);
RtlCopyMemory(&P[i], &RandomValue, Length);
}
return STATUS_SUCCESS;
}
ULONG FOR1 = 100, FOR2 = 200, FOR3 = 300, FOR4 = 400, FOR5 = 500;
ULONG Encryption_Forward1 = 1, Encryption_Forward2 = 1, Encryption_Forward3 = 1, Encryption_Forward4 = 1, Encryption_Forward5 = 1;
BOOL Request_1 = FALSE;
BOOLEAN ProtectedGameRecieved = FALSE;
BOOLEAN UsermodeAntiCheatRecieved = FALSE;
NTSTATUS IoControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS Status;
ULONG BytesIO = 0;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
// Code received from user space
ULONG ControlCode = stack->Parameters.DeviceIoControl.IoControlCode;
if (ControlCode == IO_SEND_CURRENTPROCESS && UsermodeAntiCheat < 1)
{
PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
UsermodeAntiCheat = ReadInput->UsermodeProgram;
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_READ_REQUEST);
}
if ((ULONG)UsermodeAntiCheat == (ULONG)PsGetProcessId(PsGetCurrentProcess()))
{
if (ControlCode == IO_SEND_PROCESSID && ProtectedGameRecieved == FALSE)
{
PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
ProtectedProcess = ReadInput->GameProcess;
if (ProtectedProcess > 0)
{
ProtectedGameRecieved = TRUE;
}
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_READ_REQUEST);
}
else if (ControlCode == IO_PROTECTIONT_THREADS)
{
PKERNEL_THREAD_REQUEST ReadInput = (PKERNEL_THREAD_REQUEST)Irp->AssociatedIrp.SystemBuffer;
ProtectionThreads[0] = ReadInput->ThreadID;
ProtectionThreads[1] = ReadInput->ThreadID2;
ProtectionThreads[2] = ReadInput->ThreadID3;
ProtectionThreads[3] = ReadInput->ThreadID4;
ProtectionThreads[4] = ReadInput->ThreadID5;
ProtectionThreads[5] = ReadInput->ThreadID6;
ProtectionThreads[6] = ReadInput->ThreadID7;
ProtectionThreads[7] = ReadInput->ThreadID8;
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_THREAD_REQUEST);
}
else if (ControlCode == IO_TerminateProcess)
{
PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
TerminateProcess(ReadInput->UsermodeProgram);
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_READ_REQUEST);
}
else if (ControlCode == HEARTBEATMAINSTART_FORWARD)
{
PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;
Encryption_Forward1 = ReadInput->Encrypt1;
Encryption_Forward2 = ReadInput->Encrypt2;
Encryption_Forward3 = ReadInput->Encrypt3;
Encryption_Forward4 = ReadInput->Encrypt4;
Encryption_Forward5 = ReadInput->Encrypt5;
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);
}
else if (ControlCode == HEARTBEATMAINSTART_RETURN)
{
PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;
ReadInput->Encrypt1 = Formula1(Encryption_Forward1);
ReadInput->Encrypt2 = Formula2(Encryption_Forward2);
ReadInput->Encrypt3 = Formula3(Encryption_Forward3);
ReadInput->Encrypt4 = Formula4(Encryption_Forward4);
ReadInput->Encrypt5 = Formula5(Encryption_Forward5);
//DbgPrintEx(0, 0, "HEARTBEATMAINSTART_RETURN Called: Formula1(Encryption_Forward1) %d", Formula1(Encryption_Forward1));
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);
}
else if (ControlCode == HEARTBEATCREATEPROCESS_RETURN)
{
PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;
KsecGenRandom(FOR1, sizeof(FOR1));
KsecGenRandom(FOR2, sizeof(FOR2));
KsecGenRandom(FOR3, sizeof(FOR3));
KsecGenRandom(FOR4, sizeof(FOR4));
KsecGenRandom(FOR5, sizeof(FOR5));
ReadInput->Encrypt1 = FOR1;
ReadInput->Encrypt2 = FOR2;
ReadInput->Encrypt3 = FOR3;
ReadInput->Encrypt4 = FOR4;
ReadInput->Encrypt5 = FOR5;
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);
}
else if (ControlCode == IO_VADPROTECTION)
{
PHIDE_VAD ReadInput = (PHIDE_VAD)Irp->AssociatedIrp.SystemBuffer;
if (ReadInput->pid == ProtectedProcess || ReadInput == UsermodeAntiCheat)
{
// Enable it if you like. I dont need it so eh
//BBHideVAD(ReadInput);
}
Status = STATUS_SUCCESS;
BytesIO = sizeof(HIDE_VAD);
}
else if (ControlCode == HEARTBEATCREATEPROCESS_FORWARD)
{
PKERNEL_HEARTBEAT_REQUEST ReadInput = (PKERNEL_HEARTBEAT_REQUEST)Irp->AssociatedIrp.SystemBuffer;
if (ReadInput->Encrypt1 == Formula1(FOR1))
{
if (ReadInput->Encrypt2 == Formula2(FOR2))
{
if (ReadInput->Encrypt3 == Formula3(FOR3))
{
if (ReadInput->Encrypt4 == Formula4(FOR4))
{
if (ReadInput->Encrypt5 == Formula5(FOR5))
{
//DbgPrintEx(0, 0, "Process Id ( IOCONTROL )%s\n", (ULONG)PsGetProcessId(IoGetCurrentProcess()));
Status = STATUS_SUCCESS;
// GOOD
}
else
{
if (ProtectedProcess)
{
TerminateProcess(ProtectedProcess);
}
TerminateProcess(UsermodeAntiCheat);
Status = STATUS_INVALID_PARAMETER;
//BAD
// ERROR
// TERMINATE GAME OR PROTECTION
// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
DbgPrintEx(0, 0, "Error: ReadInput->Encrypt5 == Formula5(FOR5) Encrypt: %s Formula: %s \n", ReadInput->Encrypt5, Formula5(FOR5));
}
}
else
{
if (ProtectedProcess)
{
TerminateProcess(ProtectedProcess);
}
TerminateProcess(UsermodeAntiCheat);
Status = STATUS_INVALID_PARAMETER;
//BAD
// ERROR
// TERMINATE GAME OR PROTECTION
// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
DbgPrintEx(0, 0, "Error: ReadInput->Encrypt4 == Formula4(FOR4) Encrypt: %s Formula: %s \n", ReadInput->Encrypt4, Formula4(FOR4));
}
}
else
{
if (ProtectedProcess)
{
TerminateProcess(ProtectedProcess);
}
TerminateProcess(UsermodeAntiCheat);
Status = STATUS_INVALID_PARAMETER;
//BAD
// ERROR
// TERMINATE GAME OR PROTECTION
// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
DbgPrintEx(0, 0, "Error: ReadInput->Encrypt3 == Formula3(FOR3) Encrypt: %s Formula: %s \n", ReadInput->Encrypt3, Formula3(FOR3));
}
}
else
{
if (ProtectedProcess)
{
TerminateProcess(ProtectedProcess);
}
TerminateProcess(UsermodeAntiCheat);
Status = STATUS_INVALID_PARAMETER;
//BAD
// ERROR
// TERMINATE GAME OR PROTECTION
// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
DbgPrintEx(0, 0, "Error: ReadInput->Encrypt2 == Formula2(FOR2) Encrypt: %s Formula: %s \n", ReadInput->Encrypt2, Formula2(FOR2));
}
}
else
{
if (ProtectedProcess)
{
TerminateProcess(ProtectedProcess);
}
TerminateProcess(UsermodeAntiCheat);
Status = STATUS_INVALID_PARAMETER;
//BAD
// ERROR
// TERMINATE GAME OR PROTECTION
// BLUE SCREEN OF DEATH OR WHATEVER YOU LIKE
DbgPrintEx(0, 0, "Error: ReadInput->Encrypt1 == Formula1(FOR1) Encrypt: %s Formula: %s \n", ReadInput->Encrypt1, Formula1(FOR1));
}
BytesIO = sizeof(KERNEL_HEARTBEAT_REQUEST);
}
}
else if ((ULONG)ProtectedProcess == (ULONG)PsGetProcessId(PsGetCurrentProcess()))
{
if (ControlCode == IO_RETURNANTICHEATUSERMODE_PROCESSID_GMAE)
{
PKERNEL_READ_REQUEST ReadInput = (PKERNEL_READ_REQUEST)Irp->AssociatedIrp.SystemBuffer;
ReadInput->UsermodeProgram = UsermodeAntiCheat;
Status = STATUS_SUCCESS;
BytesIO = sizeof(KERNEL_READ_REQUEST);
}
}
// Complete the request
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = BytesIO;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
// Driver's Main function. This will be called and looped through till returned, or unloaded.
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pUniStr)
{
DbgPrintEx(0, 0, "LOADED \n");
UNICODE_STRING SACDriverName, SACSymbolName;
NTSTATUS NtRet = STATUS_SUCCESS;
PDEVICE_OBJECT pDeviceObj;
RtlInitUnicodeString(&SACDriverName, L"\\Device\\SACDriver"); // Giving the driver a name
RtlInitUnicodeString(&SACSymbolName, L"\\DosDevices\\SACDriver"); // Giving the driver a symbol
UNICODE_STRING deviceNameUnicodeString, deviceSymLinkUnicodeString;
NTSTATUS NtRet2 = IoCreateDevice(pDriverObject, 0, &SACDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObj);
IoCreateSymbolicLink(&SACSymbolName, &SACDriverName);
pDriverObject->MajorFunction[IRP_MJ_CREATE] = Create;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = Close;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoControl;
pDeviceObj->Flags |= DO_DIRECT_IO;
pDeviceObj->Flags &= (~DO_DEVICE_INITIALIZING);
pDriverObject->DriverUnload = DriverUnload;
EnableCallBack();
return NtRet;
}
Im not sure why i got bluescreen of death because of this rand() function.
#include "DLLInjectorDector.h"
#include "AbortFailureDetects.h"
#include "DriverLoader\\driver.h"
#include "DriverIO.h"
#include "openssl\\md5.h"
#include "DriverIORequests.h"
#include "Formulas.h"
#include "Anti Debug.h"
#include "DLLInjectionDetector\Utils.h"
#include "Utlis.h"
#include "NamePipe.h"
#include "DigitalSignatureChecker.h"
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Softpub.h>
#include <wincrypt.h>
#include <wintrust.h>
#include <sys/types.h>
#include <signal.h>
#include <vector>
// Link with the Wintrust.lib file.
#pragma comment (lib, "wintrust")
// Varibles
HANDLE hDriver; // Driver
ULONG NamePipe1, NamePipe2, NamePipe3, NamePipe4, NamePipe5;
ULONG FOR1, FOR2, FOR3, FOR4, FOR5;
ULONG CHECK1, CHECK2, CHECK3, CHECK4, CHECK5;
ULONG CHECK_CREATEPROCESS1, CHECK_CREATEPROCESS2, CHECK_CREATEPROCESS3, CHECK_CREATEPROCESS4, CHECK_CREATEPROCESS5;
int GameProcessID = 0;
// Functions
bool CheckTestMode();
int randNum(int min, int max);
DWORD TidHeartBeat = 0;
DWORD TidGameValidChech = 0;
DWORD TidAntiDebug = 0;
DWORD tidDriverScanner = 0;
DWORD TidCommonCheatScanner = 0;
DWORD TidOverlayScanner = 0;
DWORD TidAntiKill = 0;
DWORD TidMainThread = 0;
BOOL HeartBeatThreadAntiKill = FALSE;
HANDLE hHeartBeatThread = NULL;
DWORD WINAPI HeartBeatThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
srand(time(0));
FOR1 = randNum(2, 63);
FOR2 = randNum(3, 34);
FOR3 = randNum(8, 45);
FOR4 = randNum(5, 67);
FOR5 = randNum(2, 12);
if (DriverRequest::HEARTBEATMAINSTART_FORWARD_Function(FOR1, FOR2, FOR3, FOR4, FOR5))
{
KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT_CREATEPROCESS = DriverRequest::HEARTBEATMAINSTART_RETURN_Function();
if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt1 == HeartbeatFormula::Formula1(FOR1))
{
if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt2 == HeartbeatFormula::Formula2(FOR2))
{
if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt3 == HeartbeatFormula::Formula3(FOR3))
{
if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt4 == HeartbeatFormula::Formula4(FOR4))
{
if (RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt5 == HeartbeatFormula::Formula5(FOR5))
{
KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS = DriverRequest::HEARTBEATCREATEPROCESS_RETURN_Function();
CHECK_CREATEPROCESS1 = HeartbeatFormula::Formula1(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt1);
CHECK_CREATEPROCESS2 = HeartbeatFormula::Formula2(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt2);
CHECK_CREATEPROCESS3 = HeartbeatFormula::Formula3(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt3);
CHECK_CREATEPROCESS4 = HeartbeatFormula::Formula4(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt4);
CHECK_CREATEPROCESS5 = HeartbeatFormula::Formula5(RETURNED_HEARTBEAT_CREATEPROCESS_CREATEPROCESS.Encrypt5);
if (DriverRequest::HEARTBEATCREATEPROCESS_FORWARD_Function(CHECK_CREATEPROCESS1, CHECK_CREATEPROCESS2, CHECK_CREATEPROCESS3, CHECK_CREATEPROCESS4, CHECK_CREATEPROCESS5))
{
if ( CUtils::IsSuspendedThread(TidMainThread))
{
ErrorHandler::ErrorMessage("63452 ( Thread Mismatched )", 6);
}
HeartBeatThreadAntiKill = TRUE;
Sleep(400);
}
else
{
ErrorHandler::ErrorMessage("601 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("602 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("603 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("604 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("605 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("606 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
else
{
ErrorHandler::ErrorMessage("607 ( HeartBeat System Failed )", 5);
Sleep(3000);
exit(1);
}
}
return 0;
}
BOOL GameCheckerAntiKill = FALSE;
HANDLE hGameChecker = NULL;
DWORD WINAPI GameValidCheckThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
if (GameProcessID == 0)
{
Sleep(200);
}
else
{
if (!ErrorHandler::isProcessRunning(GameProcessID))
{
ErrorHandler::ErrorMessage("901 ( Game Stopped Running )", 3);
}
}
if (CUtils::IsSuspendedThread(TidAntiDebug)
|| CUtils::IsSuspendedThread(TidAntiKill))
{
ErrorHandler::ErrorMessage("32156 ( Thread Mismatched )", 6);
}
GameCheckerAntiKill = TRUE;
}
}
BOOL AntiDebugAntiKill = FALSE;
HANDLE hAntiDebug = NULL;
DWORD WINAPI AntiDebugThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
if (AntiDebug::CheckRemoteDebuggerPresentAPI())
{
ErrorHandler::ErrorMessage("701", 6);
}
Sleep(200);
if (AntiDebug::IsDebuggerPresentAPI())
{
ErrorHandler::ErrorMessage("702", 6);
}
Sleep(200);
if (AntiDebug::HardwareBreakpoints())
{
ErrorHandler::ErrorMessage("703", 6);
}
Sleep(200);
if (AntiDebug::MemoryBreakpoints_PageGuard())
{
ErrorHandler::ErrorMessage("704", 6);
}
Sleep(200);
if (AntiDebug::UnhandledExcepFilterTest())
{
ErrorHandler::ErrorMessage("706", 6);
}
Sleep(200);
if (AntiDebug::SharedUserData_KernelDebugger())
{
ErrorHandler::ErrorMessage("707", 6);
}
Sleep(200);
if (CUtils::IsSuspendedThread(TidAntiDebug)
|| CUtils::IsSuspendedThread(TidAntiKill))
{
ErrorHandler::ErrorMessage("34524 ( Thread Mismatched )", 6);
}
AntiDebugAntiKill = TRUE;
}
}
BOOL DriversScanAntiKill = FALSE;
HANDLE hDriversScan = NULL;
DWORD WINAPI DriversScanThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
LPVOID drivers[1024];
DWORD cbNeeded;
int cDrivers, i;
if (EnumDeviceDrivers(drivers, sizeof(drivers), &cbNeeded) && cbNeeded < sizeof(drivers))
{
/*
TCHAR szDriver[1024];
cDrivers = cbNeeded / sizeof(drivers[0]);
for (i = 0; i < cDrivers; i++)
{
if (GetDeviceDriverBaseName(drivers[i], szDriver, sizeof(szDriver) / sizeof(szDriver[0])))
{
TCHAR szName[MAX_PATH] = { 0 };
GetDeviceDriverFileName(drivers[i], szName, MAX_PATH);
//_tprintf(TEXT("%d: %s\n"), i + 1, szName);
Sleep(10);
}
}*/
Sleep(100);
}
else
{
ErrorHandler::ErrorMessage("9753 ( Please Restart Your PC )", 5);
}
if (CUtils::IsSuspendedThread(TidAntiDebug)
|| CUtils::IsSuspendedThread(TidAntiKill))
{
ErrorHandler::ErrorMessage("565435 ( Thread Mismatched )", 6);
}
DriversScanAntiKill = TRUE;
}
}
BOOL CommonCheatsScannerAntiKill = FALSE;
HANDLE hCommonCheatsScanner = NULL;
DWORD WINAPI CommonCheatsScannerThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
const char DebuggingDrivers[9][20] = {
"\\\\.\\EXTREM", "\\\\.\\ICEEXT",
"\\\\.\\NDBGMSG.VXD", "\\\\.\\RING0",
"\\\\.\\SIWVID", "\\\\.\\SYSER",
"\\\\.\\TRW", "\\\\.\\SYSERBOOT",
"\0"
};
for (int i = 0; DebuggingDrivers[i][0] != '\0'; i++) {
HANDLE h = CreateFileA(DebuggingDrivers[i], 0, 0, 0, OPEN_EXISTING, 0, 0);
if (h != INVALID_HANDLE_VALUE)
{
CloseHandle(h);
ErrorHandler::ErrorMessage("2001 ( Debugging Drivers Found )", 6);
}
CloseHandle(h);
Sleep(200);
}
const char CheatingDrivers[5][20] = {
"\\\\.\\kernelhop", "\\\\.\\BlackBone",
"\\\\.\\VBoxDrv", "\\\\.\\Htsysm72FB",
"\0"
};
for (int i = 0; CheatingDrivers[i][0] != '\0'; i++) {
HANDLE hCheats = CreateFileA(CheatingDrivers[i], 0, 0, 0, OPEN_EXISTING, 0, 0);
if (hCheats != INVALID_HANDLE_VALUE)
{
CloseHandle(hCheats);
ErrorHandler::ErrorMessage("3001 ( Cheating Drivers Found )", 2);
}
CloseHandle(hCheats);
Sleep(200);
}
if (CUtils::IsSuspendedThread(TidAntiDebug)
|| CUtils::IsSuspendedThread(TidAntiKill))
{
ErrorHandler::ErrorMessage("34536 ( Thread Mismatched )", 6);
}
CommonCheatsScannerAntiKill = TRUE;
Sleep(200);
}
}
BOOL OverlayScannerAntiKill = FALSE;
HANDLE hOverlayScanner = NULL;
DWORD WINAPI OverlayScannerThread()
{
// https://www.unknowncheats.me/forum/anti-cheat-bypass/263403-window-hijacking-dont-overlay-betray.html
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
OverlayFinderParams params;
params.style = WS_VISIBLE;
params.styleEx = WS_EX_LAYERED | WS_EX_TRANSPARENT;
params.percentMainScreen = 90.0f;
params.satisfyAllCriteria = true;
std::vector<HWND> hwnds = Utlis::OverlayFinder(params);
for (int i(0); i < hwnds.size(); ++i) {
DWORD ProcessIDForOverlay = 0;
DWORD tid = GetWindowThreadProcessId(hwnds[i], &ProcessIDForOverlay);
if (ErrorHandler::isProcessRunning(ProcessIDForOverlay))
{
DriverRequest::TerminatePrcoess(ProcessIDForOverlay);
Sleep(200);
}
Sleep(200);
}
OverlayScannerAntiKill = TRUE;
Sleep(200);
}
}
BOOL AntiKillBool = FALSE;
HANDLE hAntiKill = NULL;
DWORD WINAPI AntiKillThread()
{
AntiDebug::HideThread(GetCurrentThread());
while (1)
{
if (CUtils::IsSuspendedThread(TidHeartBeat)
|| CUtils::IsSuspendedThread(tidDriverScanner)
|| CUtils::IsSuspendedThread(TidCommonCheatScanner)
|| CUtils::IsSuspendedThread(TidOverlayScanner)
|| CUtils::IsSuspendedThread(TidGameValidChech)
|| CUtils::IsSuspendedThread(TidMainThread)
|| CUtils::IsSuspendedThread(TidAntiDebug))
{
ErrorHandler::ErrorMessage("34536 ( Thread Mismatched )", 6);
}
else
{
Sleep(200);
}
}
}
bool IsSystemCodeIntegrityEnabled()
{
//https://stackoverflow.com/questions/40084077/can-i-have-any-way-to-detect-the-driver-signing-policy-status/50944791
typedef NTSTATUS(__stdcall* td_NtQuerySystemInformation)(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
struct SYSTEM_CODEINTEGRITY_INFORMATION {
ULONG Length;
ULONG CodeIntegrityOptions;
};
static td_NtQuerySystemInformation NtQuerySystemInformation = (td_NtQuerySystemInformation)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation");
SYSTEM_CODEINTEGRITY_INFORMATION Integrity = { sizeof(SYSTEM_CODEINTEGRITY_INFORMATION), 0 };
NTSTATUS status = NtQuerySystemInformation(103, &Integrity, sizeof(Integrity), NULL);
return (status && (Integrity.CodeIntegrityOptions & 1));
}
void OnExit()
{
if (GameProcessID != 0)
{
if (ErrorHandler::isProcessRunning(GameProcessID))
{
DriverRequest::TerminatePrcoess(GameProcessID);
}
}
ErrorHandler::UnloadDriver();
}
int main()
{
using namespace std;
//FreeConsole();
InitializeDLLCheck();
InitializeThreadCheck();
TidMainThread = GetCurrentThreadId();
if (IsSystemCodeIntegrityEnabled())
{
ErrorHandler::ErrorMessage("0392 Test Mode Is Enabled. Please Disable It", 6);
}
if (Utlis::IsRunAsAdministrator)
{
HANDLE CheckHandle = CreateFileA("\\\\.\\SACDriver", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (CheckHandle != INVALID_HANDLE_VALUE)
{
ErrorHandler::UnloadDriver();
CloseHandle(CheckHandle);
}
ErrorHandler::LoadDriver();
Sleep(100);
hDriver = CreateFileA("\\\\.\\SACDriver", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
//printf("File Size: %d \n", WhiteListedDLLs::GetFileSize("SAC-V2-DLL.dll"));
if (hDriver)
{
if (DriverRequest::SendCurrentProcessID())
{
hAntiDebug = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AntiDebugThread, NULL, 0, &TidAntiDebug);
srand(time(0));
FOR1 = randNum(1, 35);
FOR2 = randNum(1, 23);
FOR3 = randNum(1, 23);
FOR4 = randNum(1, 23);
FOR5 = randNum(1, 34);
if (DriverRequest::HEARTBEATMAINSTART_FORWARD_Function(FOR1, FOR2, FOR3, FOR4, FOR5))
{
KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT = DriverRequest::HEARTBEATMAINSTART_RETURN_Function();
ULONG TEST1 = HeartbeatFormula::Formula1(FOR1);
ULONG TEST2 = RETURNED_HEARTBEAT.Encrypt1;
if (RETURNED_HEARTBEAT.Encrypt1 == HeartbeatFormula::Formula1(FOR1))
{
if (RETURNED_HEARTBEAT.Encrypt2 == HeartbeatFormula::Formula2(FOR2))
{
if (RETURNED_HEARTBEAT.Encrypt3 == HeartbeatFormula::Formula3(FOR3))
{
if (RETURNED_HEARTBEAT.Encrypt4 == HeartbeatFormula::Formula4(FOR4))
{
if (RETURNED_HEARTBEAT.Encrypt5 == HeartbeatFormula::Formula5(FOR5))
{
KERNEL_HEARTBEAT_REQUEST RETURNED_HEARTBEAT_CREATEPROCESS = DriverRequest::HEARTBEATCREATEPROCESS_RETURN_Function();
CHECK_CREATEPROCESS1 = HeartbeatFormula::Formula1(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt1);
CHECK_CREATEPROCESS2 = HeartbeatFormula::Formula2(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt2);
CHECK_CREATEPROCESS3 = HeartbeatFormula::Formula3(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt3);
CHECK_CREATEPROCESS4 = HeartbeatFormula::Formula4(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt4);
CHECK_CREATEPROCESS5 = HeartbeatFormula::Formula5(RETURNED_HEARTBEAT_CREATEPROCESS.Encrypt5);
if (DriverRequest::HEARTBEATCREATEPROCESS_FORWARD_Function(CHECK_CREATEPROCESS1, CHECK_CREATEPROCESS2, CHECK_CREATEPROCESS3, CHECK_CREATEPROCESS4, CHECK_CREATEPROCESS5))
{
hHeartBeatThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)HeartBeatThread, NULL, 0, &TidHeartBeat);
hDriversScan = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DriversScanThread, NULL, 0, &tidDriverScanner);
hCommonCheatsScanner = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CommonCheatsScannerThread, NULL, 0, &TidCommonCheatScanner);
hOverlayScanner = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)OverlayScannerThread, NULL, 0, &TidOverlayScanner);
STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
PROCESS_INFORMATION ProcessInfo;
if (CreateProcess("D:\\SteamLibrary\\steamapps\\common\\Kingdom New Lands\\Kingdom.exe", NULL, NULL, NULL, TRUE, 0, NULL, NULL, &StartupInfo, &ProcessInfo))
{
BlockInput(TRUE);
Utlis::Injection(L"SAC-V2-DLL.dll", ProcessInfo.dwProcessId);
GameProcessID = ProcessInfo.dwProcessId;
if (DriverRequest::SendProcessIDs(GameProcessID))
{
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
BlockInput(FALSE);
hGameChecker = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GameValidCheckThread, NULL, 0, &TidGameValidChech);
hAntiKill = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AntiKillThread, NULL, 0, &TidAntiKill);
KERNEL_THREAD_REQUEST Threads;
Threads.ThreadID = TidAntiDebug;
Threads.ThreadID2 = TidHeartBeat;
Threads.ThreadID3 = tidDriverScanner;
Threads.ThreadID4 = TidCommonCheatScanner;
Threads.ThreadID5 = TidOverlayScanner;
Threads.ThreadID6 = TidGameValidChech;
Threads.ThreadID7 = TidAntiKill;
Threads.ThreadID8 = TidMainThread;
if (DriverRequest::SendProtectedThreadID(Threads))
{
while (1)
{
atexit(OnExit);
Sleep(4000);
if (CUtils::IsSuspendedThread(TidHeartBeat)
|| CUtils::IsSuspendedThread(tidDriverScanner)
|| CUtils::IsSuspendedThread(TidGameValidChech)
|| CUtils::IsSuspendedThread(TidCommonCheatScanner)
|| CUtils::IsSuspendedThread(TidOverlayScanner)
|| CUtils::IsSuspendedThread(TidAntiDebug)
|| CUtils::IsSuspendedThread(TidAntiKill))
{
ErrorHandler::ErrorMessage("32947 ( Thread Mismatched )", 6);
}
if (IsSystemCodeIntegrityEnabled())
{
ErrorHandler::ErrorMessage("0392 Test Mode Is Enabled. Please Disable It", 6);
}
if (OverlayScannerAntiKill && CommonCheatsScannerAntiKill && DriversScanAntiKill && AntiDebugAntiKill && HeartBeatThreadAntiKill)
{
OverlayScannerAntiKill = FALSE;
CommonCheatsScannerAntiKill = FALSE;
DriversScanAntiKill = FALSE;
AntiDebugAntiKill = FALSE;
HeartBeatThreadAntiKill = FALSE;
}
else
{
ErrorHandler::ErrorMessage("9452 ( Thread Mismatched )", 5);
}
}
}
else
{
BlockInput(FALSE);
ErrorHandler::ErrorMessage("43524 ( Thread Mismatched )", 5);
}
}
else
{
ErrorHandler::ErrorMessage("202 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("945 ( Failed To Start Game )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("207 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("206 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("205 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("204 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("203 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("249 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("201 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("301 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("67 ( Driver Not Found )", 1);
}
}
else
{
ErrorHandler::ErrorMessage("1001 ( Run As Admin )", 1);
}
return 0;
}
int randNum(int min, int max)
{
return rand() % max + min;
}

Programmatically change VersionInfo of a foreign DLL

I am trying to programmatically change the VersionInfo attributes of a DLL file. I used this article as reference.
#include <iostream>
#include <stdio.h>
#include <windows.h>
int main(int argc, char** argv) {
LPCTSTR lpszFile = "E:\\_test\\rand_test\\test.dll";
DWORD dwHandle,
dwSize;
struct {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
// determine the size of the resource information
dwSize = GetFileVersionInfoSize(lpszFile, &dwHandle);
if (0 < dwSize)
{
unsigned char* lpBuffer = (unsigned char*) malloc(dwSize);
// Get whole VersionInfo resource/structure
GetFileVersionInfo(lpszFile, 0, dwSize, lpBuffer);
char strSubBlock[37]; // fits "\\StringFileInfo\\xxxxxxxx\\CompanyName\0"
LPTSTR pValueBuffer;
HANDLE hResource = BeginUpdateResource(lpszFile, FALSE);
if (NULL != hResource)
{
UINT uTemp;
// get the language information
if (!VerQueryValue(lpBuffer, "\\VarFileInfo\\Translation", (LPVOID *) &lpTranslate, &uTemp) != FALSE)
{
printf("Error 1\n");
return 1;
}
sprintf(strSubBlock, "\\StringFileInfo\\%04x%04x\\CompanyName", lpTranslate->wLanguage, lpTranslate->wCodePage);
if (!VerQueryValue(lpBuffer, (LPTSTR) ((LPCTSTR) strSubBlock), (LPVOID *) &pValueBuffer, &uTemp)) {
printf("Error 2\n");
return 1;
}
// PROBLEM!!!
// (pValueBuffer-lpBuffer) is 0x438 (longer than the Versioninfo resource!) but should be 0xB8
// so, pValueBuffer does not point to the actual company name.
ZeroMemory(pValueBuffer, strlen(pValueBuffer) * sizeof(TCHAR));
strcpy(pValueBuffer, "My Company, Inc."); // String may only become smaller or equal, never bigger than strlen(pValueBuffer)
if (UpdateResource(hResource,
RT_VERSION,
MAKEINTRESOURCE(VS_VERSION_INFO),
lpTranslate->wLanguage, // or 0
lpBuffer,
dwSize) != FALSE)
{
EndUpdateResource(hResource, FALSE);
}
}
free(lpBuffer);
}
return 0;
}
I think I have understood everything the code does. The plan is to read the Versioninfo block, then find the position where e.g. the CompanyName lies using VerQueryValue, then change the data, and then write it back using UpdateResource.
But there is a problem: VerQueryValue should output the position where the CompanyName string lies. But instead, it gives a pointer location, which is a few hundred bytes away, so it points somewhere outside the VersionInfo structure.
What am I doing wrong and how can I make it work?
(Also, does anybody know if there is a more elegant way to do this task, maybe even remove the limitation that the string has to be smaller or equal to the original?)
version resource this is serialized tree. if you want modify it - you need deserialize it to tree structure in memory, modify node, and serialize to new memory.
despite in msdn defined several Version Information Structures, really all it have common format
struct RsrcHeader
{
WORD wLength;
WORD wValueLength;
WORD wType;
WCHAR szKey[];
// aligned on 4*n
// BYTE Value[wValueLength]; // if (wType == 0)
// or
// WCHAR Value[wValueLength]; // if (wType == 1)
// every element aligned on 4*n
// RsrcHeader childs[];
};
so possible write common parse and serialize procedures
#if DBG
#define DBG_OPT(x) _CRT_UNPARENTHESIZE(x)
#else
#define DBG_OPT(x)
#endif
class RsrcNode
{
struct RsrcHeader
{
WORD wLength;
WORD wValueLength;
WORD wType;
WCHAR szKey[];
};
C_ASSERT(sizeof(RsrcHeader) == 6);
RsrcNode* _first, *_next;
PCWSTR _name;
const void* _pvValue;
ULONG _cbValue;
WORD _wValueLength;
WORD _wType;
DBG_OPT((PCSTR _prefix)); // only for debug output
public:
bool ParseResourse(PVOID buf, ULONG size, ULONG* pLength, PCSTR prefix);
RsrcNode(DBG_OPT((PCSTR prefix = "")))
: _next(0), _first(0) DBG_OPT((, _prefix(prefix)))
{
}
~RsrcNode();
bool IsStringValue() const
{
return _wType;
}
const void* getValue(ULONG& cb)
{
cb = _cbValue;
return _pvValue;
}
void setValue(const void* pv, ULONG cb)
{
_pvValue = pv, _cbValue = cb;
_wValueLength = (WORD)(_wType ? cb / sizeof(WCHAR) : cb);
}
RsrcNode* find(const PCWSTR strings[], ULONG n);
ULONG GetSize() const;
PVOID Store(PVOID buf, ULONG* pcb) const;
};
bool RsrcNode::ParseResourse(PVOID buf, ULONG size, ULONG* pLength, PCSTR prefix)
{
union {
PVOID pv;
RsrcHeader* ph;
ULONG_PTR up;
PCWSTR sz;
};
pv = buf;
if (size < sizeof(RsrcHeader) || (up & 3))
{
return false;
}
WORD wType = ph->wType;
ULONG wValueLength = ph->wValueLength, wLength = ph->wLength;
ULONG cbValue = 0;
switch (wType)
{
case 1:
cbValue = wValueLength * sizeof(WCHAR);
break;
case 0:
cbValue = wValueLength;
break;
default:
return false;
}
*pLength = wLength;
if (wLength > size || wLength < sizeof(RsrcHeader) || cbValue >= (wLength -= sizeof(RsrcHeader)))
{
return false;
}
wLength -= cbValue;
sz = ph->szKey, _name = sz;
do
{
if (wLength < sizeof(WCHAR))
{
return false;
}
wLength -= sizeof(WCHAR);
} while (*sz++);
DbgPrint("%s%S {\n", prefix, _name);
if (up & 3)
{
if (wLength < 2)
{
return false;
}
up += 2, wLength -= 2;
}
_wType = wType, _wValueLength = (WORD)wValueLength, _cbValue = cbValue, _pvValue = pv;
if (wValueLength && wType)
{
if (sz[wValueLength - 1])
{
return false;
}
DbgPrint("%s\t%S\n", prefix, sz);
}
if (wLength)
{
if (!*--prefix) return false;
up += wValueLength;
do
{
if (up & 3)
{
if (wLength < 2)
{
return false;
}
up += 2;
if (!(wLength -= 2))
{
break;
}
}
if (RsrcNode* node = new RsrcNode(DBG_OPT((prefix))))
{
node->_next = _first, _first = node;
if (node->ParseResourse(ph, wLength, &size, prefix))
{
continue;
}
}
return false;
} while (up += size, wLength -= size);
prefix++;
}
DbgPrint("%s}\n", prefix);
return true;
}
RsrcNode::~RsrcNode()
{
if (RsrcNode* next = _first)
{
do
{
RsrcNode* cur = next;
next = next->_next;
delete cur;
} while (next);
}
DBG_OPT((DbgPrint("%s%S\n", _prefix, _name)));
}
RsrcNode* RsrcNode::find(const PCWSTR strings[], ULONG n)
{
PCWSTR str = *strings++;
if (!str || !wcscmp(str, _name))
{
if (!--n)
{
return this;
}
if (RsrcNode* next = _first)
{
do
{
if (RsrcNode* p = next->find(strings, n))
{
return p;
}
} while (next = next->_next);
}
}
return 0;
}
ULONG RsrcNode::GetSize() const
{
ULONG size = sizeof(RsrcHeader) + (1 + (ULONG)wcslen(_name)) * sizeof(WCHAR);
if (_cbValue)
{
size = ((size + 3) & ~3) + _cbValue;
}
if (RsrcNode* next = _first)
{
do
{
size = ((size + 3) & ~3) + next->GetSize();
} while (next = next->_next);
}
return size;
}
PVOID RsrcNode::Store(PVOID buf, ULONG* pcb) const
{
union {
RsrcHeader* ph;
ULONG_PTR up;
PVOID pv;
};
pv = buf;
ph->wType = _wType;
ph->wValueLength = _wValueLength;
ULONG size = (1 + (ULONG)wcslen(_name)) * sizeof(WCHAR), cb;
memcpy(ph->szKey, _name, size);
up += (size += sizeof(RsrcHeader));
if (_cbValue)
{
up = (up + 3) & ~3;
memcpy(pv, _pvValue, _cbValue);
up += _cbValue;
size = ((size + 3) & ~3) + _cbValue;
}
if (RsrcNode* next = _first)
{
do
{
up = (up + 3) & ~3;
pv = next->Store(pv, &cb);
size = ((size + 3) & ~3) + cb;
} while (next = next->_next);
}
reinterpret_cast<RsrcHeader*>(buf)->wLength = (WORD)size;
*pcb = size;
return pv;
}
with this helper structure we can update version in next way:
#include "VerHlp.h"
BOOL UpdateVersion(PVOID pvVersion, ULONG cbVersion, PVOID& pvNewVersion, ULONG& cbNewVersion)
{
BOOL fOk = FALSE;
char prefix[16];
memset(prefix, '\t', sizeof(prefix));
prefix[RTL_NUMBER_OF(prefix) - 1] = 0;
*prefix = 0;
if (RsrcNode* node = new RsrcNode)
{
if (node->ParseResourse(pvVersion, cbVersion, &cbVersion, prefix + RTL_NUMBER_OF(prefix) - 1))
{
static const PCWSTR str[] = {
L"VS_VERSION_INFO", L"StringFileInfo", 0, L"CompanyName"
};
if (RsrcNode *p = node->find(str, RTL_NUMBER_OF(str)))
{
if (p->IsStringValue())
{
ULONG cb;
const void* pvCompanyName = p->getValue(cb);
DbgPrint("CompanyName: %S\n", pvCompanyName);
static WCHAR CompanyName[] = L"[ New Company Name ]";
if (cb != sizeof(CompanyName) ||
memcmp(pvCompanyName, CompanyName, sizeof(CompanyName)))
{
p->setValue(CompanyName, sizeof(CompanyName));
cbVersion = node->GetSize();
if (pvVersion = LocalAlloc(0, cbVersion))
{
node->Store(pvVersion, &cbNewVersion);
pvNewVersion = pvVersion;
fOk = TRUE;
}
}
}
}
}
delete node;
}
return fOk;
}
struct EnumVerData
{
HANDLE hUpdate;
BOOL fDiscard;
};
BOOL CALLBACK EnumResLangProc(HMODULE hModule,
PCWSTR lpszType,
PCWSTR lpszName,
WORD wIDLanguage,
EnumVerData* Ctx
)
{
if (HRSRC hResInfo = FindResourceExW(hModule, lpszType, lpszName, wIDLanguage))
{
if (HGLOBAL hg = LoadResource(hModule, hResInfo))
{
if (ULONG size = SizeofResource(hModule, hResInfo))
{
if (PVOID pv = LockResource(hg))
{
if (UpdateVersion(pv, size, pv, size))
{
if (UpdateResource(Ctx->hUpdate, lpszType, lpszName, wIDLanguage, pv, size))
{
Ctx->fDiscard = FALSE;
}
LocalFree(pv);
}
}
}
}
}
return TRUE;
}
ULONG UpdateVersion(PCWSTR FileName)
{
ULONG dwError = NOERROR;
EnumVerData ctx;
if (ctx.hUpdate = BeginUpdateResource(FileName, FALSE))
{
ctx.fDiscard = TRUE;
if (HMODULE hmod = LoadLibraryExW(FileName, 0, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))
{
if (!EnumResourceLanguages(hmod, RT_VERSION,
MAKEINTRESOURCE(VS_VERSION_INFO),
(ENUMRESLANGPROCW)EnumResLangProc, (LONG_PTR)&ctx))
{
dwError = GetLastError();
}
FreeLibrary(hmod);
}
else
{
dwError = GetLastError();
}
if (!dwError && !EndUpdateResourceW(ctx.hUpdate, ctx.fDiscard))
{
dwError = GetLastError();
}
}
else
{
dwError = GetLastError();
}
return dwError;
}

Only printing last line of txt file when reading into struct array in C

I am reading from a txt file into an array of structures. Example txt:
-4.5 -1 0 0
4.0 1 0 0
8 0 1 2
12.1 0 -6 1
-3.2 2.5 -3.0 4
The 4 values of each line correspond to the 4 values in the structure. The file may contain up to 100 lines (MAX is defined as 100). With the following code I am trying to store each line into the respective index of the struct array and then print:
FILE *fileName = NULL;
typedef struct chargeData_struct {
double Q, x, y, z;
} ChargeData;
ChargeData values[MAX], *p = values;
fileName = fopen("charge2.txt", "r");
if (fileName == NULL)
{
printf("ERROR: Could not open file.");
}
int k = 0;
while (fscanf(fileName, "%lf %lf %lf %lf", &p[k].Q, &p[k].x, &p[k].y, &p[k].z) != EOF);
{
printf("%f %f %f %f\n", p[k].Q, p[k].x, p[k].y, p[k].z);
k++;
}
fclose(fileName);
However, only the last line of the txt file is printed. Is the same index of the struct array being overwritten each time?
You are using an extra semicolon which makes all the trouble, here:
while (fscanf(...) != EOF);
{
...
Remove it and you should be fine.
What happens with your code is that while(..); is equivalent to this:
while(...)
{
; // do nothing
}
thus does not enter the body (the one you think is the body) of your loop (since the actual body does nothing). However scanf() continues to parse the file, and then this section of your code executes:
{
printf("%f %f %f %f\n", p[k].Q, p[k].x, p[k].y, p[k].z);
k++;
}
independently, where the curly braces are treated like they wanted to state scope.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define LINE_BUFFER_LEN (512)
#define RESERVE_NEWLINDE 0
#define AUTO_FILTER_NEWLINDE 1
typedef int (* LINE_READER)(char * pstrLine, int uiBufferLen, void * pvData);
typedef struct st_HW_SSP_CONFIG
{
const char * pstrConfigPath;
LINE_READER pfLineReader;
FILE * pstFile;
void * pvData;
int CurrentLine;
int Flag;
} CONFIG_ST;
int CloseConfig(CONFIG_ST * pstConfig)
{
if (!pstConfig)
{
// record error
return -1;
}
if (fclose(pstConfig->pstFile))
{
// record error
}
return 0;
}
int OpenConfigFile(const char * pstrFilePath, CONFIG_ST * pstConfig)
{
FILE * pstFile = NULL;
if ((!pstrFilePath) || (!pstConfig))
{
return -1;
}
pstFile = fopen(pstrFilePath, "r");
if (!pstFile)
{
return -1;
}
pstConfig->pstFile = pstFile;
pstConfig->pstrConfigPath = pstrFilePath;
pstConfig->Flag = RESERVE_NEWLINDE;
return 0;
}
int IsNullStr(const char *pcStr)
{
const char *pcTmp = pcStr;
while ('\0' != *pcTmp)
{
if (!isspace(*pcTmp))
{
return 0;
}
pcTmp++;
}
return 1;
}
int IsEffectiveLine(char acFileLineBuffer[LINE_BUFFER_LEN])
{
if (0 == strlen(&acFileLineBuffer[0]))
{
return 0;
}
if ('#' == acFileLineBuffer[0]) // strip as a comment line
{
return 0;
}
if (IsNullStr(&acFileLineBuffer[0]))
{
return 0;
}
return 1;
}
void FilterNewLine(char* pcLine, int MaxNumLen)
{
int uiLen = strlen(pcLine);
if (uiLen > 1)
{
if ('\n' == pcLine[uiLen - 1])
{
pcLine[uiLen - 1] = '\0';
if (uiLen > 2)
{
if ('\r' == pcLine[uiLen - 2])
{
pcLine[uiLen - 2] = '\0';
}
}
}
}
return;
}
int ReadConfigFile(CONFIG_ST * pstConfig)
{
char acFileLineBuffer[LINE_BUFFER_LEN] = {0};
char * pstrRead = NULL;
int Ret = 0;
if (!pstConfig)
{
return -1;
}
if ((!pstConfig->pstFile) || (!pstConfig->pfLineReader))
{
return -1;
}
rewind(pstConfig->pstFile);
pstConfig->CurrentLine = 0;
do
{
memset((void *)&acFileLineBuffer[0], 0, LINE_BUFFER_LEN);
pstrRead = fgets(&acFileLineBuffer[0], LINE_BUFFER_LEN - 1, pstConfig->pstFile);
if (pstrRead)
{
pstConfig->CurrentLine ++;
if (0 == IsEffectiveLine(acFileLineBuffer))
{
continue;
}
if (AUTO_FILTER_NEWLINDE == pstConfig->Flag)
{
FilterNewLine(acFileLineBuffer, LINE_BUFFER_LEN - 1);
}
if (pstConfig->pfLineReader)
{
Ret = pstConfig->pfLineReader(&acFileLineBuffer[0],
LINE_BUFFER_LEN,
pstConfig->pvData);
if (Ret)
{
break;
}
}
}
}
while (pstrRead);
return Ret;
}
int ReadConfigFileEx(const char * pFilePath,
LINE_READER pfReader,
void * pData, int Flag)
{
int Ret = 0;
CONFIG_ST stConfig = {0};
Ret = OpenConfigFile(pFilePath, &stConfig);
if (Ret)
{
return Ret;
}
stConfig.pfLineReader = pfReader;
stConfig.pvData = pData;
stConfig.Flag = Flag;
Ret = ReadConfigFile(&stConfig);
CloseConfig(&stConfig);
return Ret;
}
int StringSplit(char *pcStr, char cFlag,
char * pstArray[], int MaxNum,
int *pNum)
{
char * pcStrTemp = 0;
unsigned int uiIndex = 0;
pcStrTemp = pcStr;
while (pcStrTemp)
{
pstArray[uiIndex] = pcStrTemp;
pcStrTemp = strchr(pcStrTemp, cFlag);
if (pcStrTemp)
{
*pcStrTemp = '\0';
pcStrTemp ++;
uiIndex ++;
}
if (uiIndex >= MaxNum)
{
break;
}
}
if (0 != MaxNum)
{
*pNum = uiIndex >= MaxNum ? (MaxNum - 1) : uiIndex;
}
else
{
*pNum = 0;
}
return 0;
}
int MyLineReader(char * pstrLine, int uiBufferLen, void * pvData)
{
printf("Read line:[%s]\r\n", pstrLine);
char *pArray[8] = {0};
int Num = 0;
int index = 0;
StringSplit(pstrLine, ' ', pArray, 8, &Num);
for (index = 0; index <= Num; index ++)
{
printf("Get value :[%s]\r\n", pArray[index]);
}
return 0;
}
int main(int argc, char * argv[])
{
int ret = 0;
if (argc != 2)
{
printf("Please input file to read.\r\n");
return 0;
}
ret = ReadConfigFileEx(argv[1], MyLineReader, NULL, AUTO_FILTER_NEWLINDE);
if (ret)
{
printf("Open file error.\r\n");
}
return 0;
}

C - segmentation fault on long running while loop

I wrote small daemon for rotating screen on Thinkpad X41 convertible laptop using built-in motion sensor (used by harddisk active protection system) or manually by button. Program works very well, but after some amount of time (5 to 15 minutes) will crash with segfault.
I know there are lot of scripts on the internet to do this written in bash or python, but none of them suit my needs and vision how should program work.
I know that for example mentioned bash is probably better for this, but I have zero experiences with it compared to C In which I have at least minimal basic experiences from few high school lessons, so I choose this.
here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define TRUE 1
#define FALSE 0
#define NIL -1
#define XRANDR_GREP_COMMAND "xrandr -q --verbose|grep LVDS1|cut -b37-37"
#define DAEMON_LOCK_FILE "/dev/shm/thinkrotate.lock"
#define DAEMON_STATE_FILE "/dev/shm/thinkrotate.st"
#define SWIVEL_STATE_FILE "/sys/devices/platform/thinkpad_acpi/hotkey_tablet_mode"
#define GYRO_STATE_FILE "/sys/devices/platform/hdaps/position"
#define BUBBLE_TERMINATED "notify-send 'Ukončenie programu' 'ThinkRotate démon dostal príkaz na ukončenie'"
#define BUBBLE_SWIVEL_DOWN "notify-send 'Notebook v tablet móde' 'Veko bolo sklopené, aktivovaná automatická rotácia'"
#define BUBBLE_SWIVEL_UP "notify-send 'Notebook v štandartnom režime' 'Rotácia je deaktivovaná'"
#define BUBBLE_RETURN_POSITION "notify-send 'Automatická rotácia zapnutá' 'Pre vypnutie automatickej rotácie obrazu stlačte tlačítko rotácie.'"
#define BUBBLE_START_MANUAL_ROTATION "notify-send 'Automatická rotácia vypnutá' 'Rotácia bude zapnutá znovu až pri návrate do tejto polohy, dovtedy na otáčanie obrazu používajte tlačidlo.'"
#define SWIVEL_DOWN_COMMANDS ""
#define SWIVEL_UP_COMMANDS ""
#define WIDTH_COMMANDS ""
#define HEIGHT_COMMANDS ""
int get_lock(void) {
int fdlock;
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 1;
if((fdlock = open(DAEMON_LOCK_FILE, O_WRONLY|O_CREAT, 0666)) == -1) { return 0; }
if(fcntl(fdlock, F_SETLK, &fl) == -1) { return 0; }
return 1;
}
int next_rotation(int direction) {
int next;
int pos;
pos = current_pos();
if (direction == 1) {
switch (pos) {
case 0:
next = 1;
break;
case 1:
next = 2;
break;
case 2:
next = 3;
break;
case 3:
next = 0;
break;
}
} else if (direction == 2) {
switch (pos) {
case 0:
next = 3;
break;
case 1:
next = 0;
break;
case 2:
next = 1;
break;
case 3:
next = 2;
break;
}
}
return next;
}
int current_pos(void) {
FILE *frotpos;
char rotpos;
int pos;
frotpos = popen(XRANDR_GREP_COMMAND, "r");
fscanf(frotpos, "%c", &rotpos);
fclose(frotpos);
switch (rotpos) {
case 110:
pos = 0;
break;
case 108:
pos = 1;
break;
case 105:
pos = 2;
break;
case 114:
pos = 3;
break;
}
return pos;
}
void rotate(int poz) {
char buff[32];
if ((poz == 2)||(poz == 0)) {
system(WIDTH_COMMANDS);
} else {
system(HEIGHT_COMMANDS);
}
sprintf(buff, "xrandr -o %i", poz);
system(buff);
}
int main(int argc, char *argv[]) {
if(!get_lock()) {
if (argc >= 2) {
int cmd;
FILE *fparams;
fparams = fopen(DAEMON_STATE_FILE, "w");
if (!strncmp(argv[1], "r", 1)) { cmd = 1; }
else if (!strncmp(argv[1], "l", 1)) { cmd = 2; }
else if (!strncmp(argv[1], "k", 1)) { cmd = 0; }
fprintf(fparams, "%i", cmd);
fclose(fparams);
}
return 1;
}
int autorotate = TRUE;
int prevmode = NIL;
FILE *fstate;
int tabletmode;
FILE *fgyrovals;
char gyroval_x[5];
char gyroval_y[5];
int x;
int y;
FILE *fargs;
int argum = NIL;
int next_p;
int prev_p = current_pos();
int last_auto_p = NIL;
while (TRUE) {
fstate = fopen(SWIVEL_STATE_FILE, "r");
fscanf(fstate, "%d", &tabletmode);
if (fargs = fopen(DAEMON_STATE_FILE, "r")) {
if (fscanf(fargs, "%d", &argum) == NIL) { argum = NIL; }
}
fargs = fopen(DAEMON_STATE_FILE, "w");
fclose(fargs);
fclose(fstate);
if (argum == 0) {
system(BUBBLE_TERMINATED);
return 1;
}
if (prevmode != tabletmode) {
if (tabletmode) {
system(BUBBLE_SWIVEL_DOWN);
system(SWIVEL_DOWN_COMMANDS);
} else {
system(BUBBLE_SWIVEL_UP);
system(SWIVEL_UP_COMMANDS);
rotate(0);
}
}
if (tabletmode) {
if (argum == 1 || argum == 2) {
next_p = next_rotation(argum);
if (next_p == last_auto_p) {
rotate(next_p);
autorotate = TRUE;
last_auto_p = NIL;
system(BUBBLE_RETURN_POSITION);
} else if ((autorotate)&&(current_pos() == last_auto_p)) {
autorotate = FALSE;
system(BUBBLE_START_MANUAL_ROTATION);
} else {
if (autorotate) {
system(BUBBLE_START_MANUAL_ROTATION);
last_auto_p = current_pos();
} else {
rotate(next_p);
}
autorotate = FALSE;
}
}
if (autorotate) {
fgyrovals = fopen(GYRO_STATE_FILE, "r");
fscanf(fgyrovals, "(%4[^,], %4[^)]", &gyroval_x, &gyroval_y);
fclose(fgyrovals);
x = atoi(gyroval_x);
y = atoi(gyroval_y) * (-1);
if (y < 465) {
if (x < 210) {
next_p = 1;
} else if (x > 425) {
next_p = 3;
} else {
next_p = 2;
}
} else if (y > 525) {
if (x < 210) {
next_p = 1;
} else if (x > 425) {
next_p = 3;
} else {
next_p = 0;
}
} else {
if (x < 305) {
next_p = 1;
} else if (x > 345) {
next_p = 3;
}
}
if (next_p != prev_p) {
rotate(next_p);
prev_p = next_p;
}
}
} else {
if (argum == 1 || argum == 2) {
system(BUBBLE_SWIVEL_UP);
}
}
prevmode = tabletmode;
sleep(1);
}
return 0;
}
Thanks to comment of user "inspired". Now the program is running more than a hour without segfault.
if (fargs = fopen(DAEMON_STATE_FILE, "r")) {
if (fscanf(fargs, "%d", &argum) == NIL) { argum = NIL; }
fclose(fargs);
}
fargs = fopen(DAEMON_STATE_FILE, "w");
fclose(fargs);
As said, file should be closed before opened next time for writing.

Resources