I am creating a self-mutation under Windows, but when I try to change my permissions page boundaries, it works under Dev C++, but the same code doesn't work under Visual Studio 2017. Once I compile it works, but it always return me original function result 1, mutation 1 when it should be 42.
Dev C++
int change_page_permissions_of_address(void *addr) {
// Move the pointer to the page boundary
int page_size = getpagesize();
DWORD dwOldProtect;
addr -= (unsigned uintptr_t)addr % page_size; // it works under dev c++
if(VirtualProtect(addr, page_size, PAGE_EXECUTE_READWRITE,&dwOldProtect) == -1) {
return -1;
}
return 0;
}
Visual Studio 2017
int change_page_permissions_of_address(void* address) {
// Move the pointer to the page boundary
unsigned char* addr = reinterpret_cast<unsigned char *>(address); // cast before operation
int page_size = getpagesize();
DWORD dwOldProtect;
addr -= (uintptr_t)addr % page_size; // doesnt work under visual studio
if (VirtualProtect(addr, page_size, PAGE_EXECUTE_READWRITE, &dwOldProtect) == -1) {
return -1;
}
return 0;
}
main
int main(){
void *foo_addr = (void*)foo;
if(change_page_permissions_of_address(foo_addr) == -1) {
fprintf(stderr, "Error while changing page permissions of foo(): %s\n", strerror(errno));
return 1;
}
// Call the unmodified foo()
puts("Calling foo...");
foo();
// Change the immediate value in the addl instruction in foo() to 42
unsigned char *instruction = (unsigned char*)foo_addr + 18;
*instruction = 0x2A;
// Call the modified foo()
puts("Calling foo..., but I am the self-modifying");
foo();
return 0;
}
self-mutation_visual
Related
I'm trying to edit pointer's value with dll but it crashes the program. Pointer is 100% correct (checked and tested with cheat engine). My goal is to change its value to 1 (I can do it via cheat engine, but I need to convert it to code).
typedef void(__fastcall* _wh)(int val);
_wh wh;
uintptr_t FinalAddress(uintptr_t ptr, std::vector<DWORD> offsets)
{
uintptr_t addr = ptr;
for (unsigned int i = 0; i < offsets.size(); ++i)
{
addr = *(uintptr_t*)addr;
addr += offsets[i];
}
return addr; // returns the main pointer from needed assets
}
DWORD WINAPI HackThread(HMODULE hModule)
{
AllocConsole();
FILE* f;
freopen_s(&f, "CONOUT$", "w", stdout);
std::cout << "dll injected\n" << std::endl;
uintptr_t moduleBase = (uintptr_t)GetModuleHandle(L"Soria2.pl.exe");
uintptr_t adres = FinalAddress(moduleBase + 0x267D94, {0xC, 0x66C});
wh = (_wh)adres; // access the pointer's pointer to edit the value;
std::cout << wh;
while (true)
{
if (GetAsyncKeyState(VK_SHIFT) & 1)
{
wh(1);
}
Sleep(10);
}
fclose(f);
FreeConsole();
FreeLibraryAndExitThread(hModule, 0);
return 0;
}
Ok I've figured it out. It turned out that the thing I wanted was just a variable and I wanted to call the function. This part was problematic:
wh = (_wh)adres; // access the pointer's pointer to edit the value;
I changed it to:
int* wallHack = (int*)adres
and simply changed the value to:
*wallhack = 1
I am writting a self-mutation code , and its original value before overwrite is 1,but after the overwrite should be 42. I think I am missing some aspecs because I got 1 on both original and mutation overwrite. my complete code looks like this gist link , but the original source was written under *unix https://shanetully.com/2013/12/writing-a-self-mutating-x86_64-c-program/
#include <windows.h>
#include <iostream>
using namespace std;
int getpagesize();
void foo(void);
int change_page_permissions_of_address(void *addr);
int getpagesize() {
SYSTEM_INFO si;
GetSystemInfo(&si);
return unsigned(si.dwPageSize);
}
void foo(void) {
int i = 0;
i++;
printf("i: %d\n", i);
}
int change_page_permissions_of_address(void *addr) {
// Get total function size
int page_size = getpagesize();
DWORD dwOldProtect;
// Obtain the addresses for the functions so we can calculate size.
uintptr_t tmp = (uintptr_t)addr-(uintptr_t)addr%page_size;
addr = (void*)tmp;
// We need to give ourselves access to modifify data at the given address
if (VirtualProtect(addr, page_size, PAGE_EXECUTE_READWRITE, &dwOldProtect) == -1) {
return -1;
}
return 0;
}
int main() {
void *foo_addr = (void*)foo;
if (change_page_permissions_of_address(foo_addr) == -1) {
printf("Error while changing page permissions of foo(): %s\n");
return 1;
}
// Call the unmodified foo()
puts("Calling foo...");
foo();
// Change the immediate value in the addl instruction in foo() to 42
unsigned char *instruction = (unsigned char*)foo_addr + 18;
*instruction = 0x2A;
puts("Calling foo..., but I am the self-modifying");
foo();
cin.get();
return 0;
}
Check of VirtualProtect is incorrect as it returns FALSE, not -1 in case of an error. Also I suspect that you will need to obtain a pointer to a starting page of the region of pages that foo belongs to and it is not clear where did you get offset 18 from.
I have problem with program. I don't know which method or function (I have problem with name) "measurementSensor" is good. I wrote first code to give address device.
class I2CConnection{
private:
int fd;
char* fileName;
int flag;
int isOpen;
int currentAddress;
public:
I2CConnection(char *name,int flag = O_RDWR){
this->fileName = name;
this->isOpen = 0;
}
int send(char* buf[],unsigned int size){
if((write(this->fd,buf,size)) < size){
printf("Error writing to i2c slave\n");
}else{
return(size);
}
}
int recive(char* buf[],unsigned int size){
if((read(this->fd,buf,size)) <size){
printf("Error writing to i2c slave\n");
}else{
return(size);
}
}
int connectTo(int address){
if(ioctl(this->fd,I2C_SLAVE,address) < 0){
printf("Unable to get bus access to talk to slave\n");
return(0);
}else{
this->currentAddress = address;
return(1);
}
}
int openConnection(){
if((fd = open(fileName, O_RDWR)) < 0){
printf("Failed to open i2c port\n");
this->isOpen = 0;
}else{
this->isOpen = 1;
}
return(this->isOpen)
}
int closeConnection(){
if(close(fd)==0){
this->isOpen = 0;
}else{
this->isOpen = 1;
}
return(!this->isOpen);
}
~I2CConnection(){
if ( this->isOpen){
closeConnection();
}
}
}
class SonicSensor{
private:
int address;
unsigned int units;
I2CConnection* conn;
unsigned int value;
public:
SonicSensor(I2CConnection* c,int addr){
this->address = addr;
this->conn = c;
}
void changeUnits(int u){
this->units = u;
}
unsigned int measurementSensor(char* buf[]){
buf[0] = 0;
buf[1] = 0x51;
c.send(buf,2);
buf[0] = 0xA0;
c.send(buf,1);
buf[0] = 0xAA;
c.send(buf,1);
buf[0] = 0xA5;
c.send(buf,1);
buf[0] = 0xF2;
c.send(buf,1);
}
~SonicSensor(){
}
};
The problem is the error: invalid conversion from int to char*. I can't found solved for this error.
You should be working with arrays of bytes, not arrays of pointers-to-bytes. Unless your target platform uses 8-bit pointers, you will end up writing pointer-sized values to your I2C device instead of single bytes as intended. On a 32-bit system, for the first command instead of sending two bytes (00 and 51) you would actually send 8 bytes (00 00 00 00 and 00 00 00 51).
Your I2CConnection methods send and receive should be declared as:
int send(const char* buf, unsigned int size)
int receive(char* buf, unsigned int size)
Likewise, your SonicSensor class measurementSensor method does not appear to need an input argument, so it could be done as:
unsigned int measurementSensor() {
char buf[2];
...
original code is
#define MAX_FRAMES 10000
#define MS_BETWEEN_FRAMES CONFIG_FB_MSM_LOGO_ANIMATE_FPS
int load_565rle_image(char *filename, bool bf_supported);
struct delayed_work rle_animate_work;
static void load_565rle_animate(struct work_struct *work)
{
int i, ret = 0, bf_supported = 0;
char filename [20];
struct fb_info *info = registered_fb[0];
set_fs(KERNEL_DS);
printk(KERN_INFO "Starting kernel boot animation\n");
for (i = 1; i < MAX_FRAMES; i++) {
sprintf(filename, "/res/bootlogo/%d.rle", i);
ret = load_565rle_image(filename, bf_supported);
sys_unlink(filename);
if (ret == -ENOENT)
break;
info->fbops->fb_open(info, 0);
info->fbops->fb_pan_display(&info->var, info);
msleep(MS_BETWEEN_FRAMES);
}
}
static int __init logo_animate_init(void)
{
INIT_DELAYED_WORK(&rle_animate_work, load_565rle_animate);
schedule_delayed_work(&rle_animate_work, 5 * HZ);
return 0;
}
static void __exit logo_animate_exit(void)
{
return;
}
this make kernel logo animated, by loading series of *.rle image continuously ie 1.rle>2.rle>3.rle>4.rle>5.rle and so on.
the way it was originally written is to stop loading those images when it reaches end of image filename, ie if last filename is 5.rle, it stops and halted there.
basicaly what i'm trying to do now is looping, when it reaches last file (5.rle) it'll continue loading from the beginning again (1.rle).
so i added CONFIG_FB_MSM_LOGO_ANIMATE_LOOP
static void load_565rle_animate(struct work_struct *work)
{
int i, ret = 0, bf_supported = 0;
char filename [20];
struct fb_info *info = registered_fb[0];
set_fs(KERNEL_DS);
printk(KERN_INFO "Starting kernel boot animation\n");
for (i = 1; i < MAX_FRAMES; i++) {
sprintf(filename, "/res/bootlogo/%d.rle", i);
ret = load_565rle_image(filename, bf_supported);
sys_unlink(filename);
if (ret == -ENOENT)
#ifdef CONFIG_FB_MSM_LOGO_ANIMATE_LOOP
return ret;
#else
break;
#endif
info->fbops->fb_open(info, 0);
info->fbops->fb_pan_display(&info->var, info);
msleep(MS_BETWEEN_FRAMES);
}
}
but when the CONFIG_FB_MSM_LOGO_ANIMATE_LOOP is enable, it give compile error of 'warning: ‘return’ with a value, in function returning void [enabled by default]'
which halted the compile process. any thoughts?
#ifdef CONFIG_FB_MSM_LOGO_ANIMATE_LOOP
return ret;
#else
break;
#endif
this is beeing preprocessed by preprocessr and result in returning int ret from your function when CONFIG_FB_MSM_LOGO_ANIMATE_LOOP is defined. So
‘return’ with a value, in function returning void
seems to be quite reasonable hint.
solution:
change also function returned type then or change it to:
#ifdef `CONFIG_FB_MSM_LOGO_ANIMATE_LOOP`
return;
#else
break;
#endif
I want to search a file which may be present in any drives such as C:\, D:\ etc. Using GetLogicalDriveStrings I can able to get the list of drives but when I add anything extra for the output, I am getting a null in the output prompt. Here is my code:
#include "StdAfx.h"
#include <windows.h>
#include <stdio.h>
#include <conio.h>
// Buffer length
DWORD mydrives = 100;
// Buffer for drive string storage
char lpBuffer[100];
const char *extFile = "text.ext";
// You may want to try the wmain() version
int main(void)
{
DWORD test;
int i;
test = GetLogicalDriveStrings(mydrives, (LPWSTR)lpBuffer);
if(test != 0)
{
printf("GetLogicalDriveStrings() return value: %d, Error (if any): %d \n", test, GetLastError());
printf("The logical drives of this machine are:\n");
// Check up to 100 drives...
for(i = 0; i<100; i++)
printf("%c%s", lpBuffer[i],extFile);
printf("\n");
}
else
printf("GetLogicalDriveStrings() is failed lor!!! Error code: %d\n", GetLastError());
_getch();
return 0;
}
I want above output as C:\text.ext D:\text.ext ... rather I am getting text.ext only. I am using Microsoft Visual C++ 2010 Express
GetLogicalDriveStrings() returns a double-null terminated list of null-terminated strings. E.g., say you had drives A, B and C in your machine. The returned string would look like this:
A:\<nul>B:\<nul>C:\<nul><nul>
You can use the following code to iterate through the strings in the returned buffer and print each one in turn:
DWORD dwSize = MAX_PATH;
char szLogicalDrives[MAX_PATH] = {0};
DWORD dwResult = GetLogicalDriveStrings(dwSize,szLogicalDrives);
if (dwResult > 0 && dwResult <= MAX_PATH)
{
char* szSingleDrive = szLogicalDrives;
while(*szSingleDrive)
{
printf("Drive: %s\n", szSingleDrive);
// get the next drive
szSingleDrive += strlen(szSingleDrive) + 1;
}
}
Note that the details of how the function works, including the example code that I shamelessly copied and pasted, can be found by reading the docs.
Did you mean to put the printf in the loop?
Currently, you set extFile 100 times (just to be sure?!)
for(i = 0; i<100; i++)
extFile = "text.ext";
You meant to show all the drive letters in a loop:
for(i = 0; i<100; i++)
{
extFile = "text.ext";
printf("%c%s", lpBuffer[i], extFile); //I guess you mean extFile here?
}
DWORD dwSize = MAX_PATH;
WCHAR szLogicalDrives[MAX_PATH] = { 0 };
DWORD dwResult = GetLogicalDriveStrings(dwSize, szLogicalDrives);
CStringArray m_Drives;
m_Drives.RemoveAll();
if (dwResult > 0 && dwResult <= MAX_PATH)
{
WCHAR* szSingleDrive = szLogicalDrives;
while (*szSingleDrive)
{
UINT nDriveType = GetDriveType(szSingleDrive);
m_Drives.Add(CString(szSingleDrive, 2));
// get the next drive
szSingleDrive += wcslen(szSingleDrive) + 1;
}
}
return m_Drives;
class DriveList {
protected:
LPTSTR m_driveList;
DWORD m_driveCount;
DWORD m_bufSize = 32 * sizeof(TCHAR);
public:
virtual ~DriveList() {
free(m_driveList);
}
DriveList() {
m_driveList = (LPTSTR)malloc(m_bufSize);
}
int getDriveCount() const {
return m_driveCount;
}
TCHAR operator[] (const int index) const {
return m_driveList[index];
}
void loadDriveList() {
DWORD mask;
if((mask = GetLogicalDrives()) == 0) {
throw;
}
m_driveCount = 0;
for(int x = 0; x <= 25; x++ ) {
if(mask & 1) {
m_driveList[m_driveCount] = TCHAR(65 + x);
m_driveCount += 1;
}
mask >>= 1;
}
}
};