D
D
Denis Goncharenko2018-06-01 08:22:56
C++ / C#
Denis Goncharenko, 2018-06-01 08:22:56

Why is reading not allowed?

Whole code:

#include <fstream>
#include <iostream> 
#include <stdio.h>
#include <iomanip>  
#include <windows.h>

using namespace std;

unsigned char	b[] = "\xa1\x00\x70\xe8\x00";
int mySequency[256] = { 3 };

void *exec = VirtualAlloc(0, sizeof b, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
int main()
{
  memcpy(exec, b, sizeof b);
  ((void(*)())exec)();

  system("pause");
  return 0;
}

A simple shellcode is executed without problems, for example, putting some number into a register, but when it tries to read or write the mySequency variable, we get an error:
5b10d7464d08f055127010.jpeg
I tried to do:
DWORD old_protect;
VirtualProtect((DWORD*)mySequency, 256, PAGE_READWRITE, &old_protect);

Doesn't affect at all.
Given the byte code of the following instruction:
mov eax, dword ptr[mySequency]
In the form of assembler insertion in Visual Studio, it works without problems. I suspect that something else needs to be tweaked in the project configs, but it seems that I have already turned everything off ...
I dug into the configs, it seems like sometimes errors with memory disappear, but now it appears:
5b10e44aa2d3f371937173.jpeg

Answer the question

In order to leave comments, you need to log in

2 answer(s)
R
Rsa97, 2018-06-01
@Rsa97

No, your opcode matches the instruction
. Who told you that the mySequency variable is located at 0xe87000? Each time you run the program, its address may be different.

M
Mercury13, 2018-06-01
@Mercury13

Great, you've already run some code. But the challenge agreement did not survive.
1. Use the STDCALL calling convention. Then the function will have to clean up after itself. Since there are no local variables in it, no cleanup is required.

typedef uint32_t WINAPI (*SomeFunc)();
uint32_t result = (SomeFunc)exec();

At the same time, this will allow you to see that the function has started. In either case, the return value will be in eax.
2. At the end of our function, put RET (CB opcode, if I'm not mistaken).
3. Calculate and patch the address of the variable into our code.
Starting with protected mode 386, we have "flat memory". Segments are used only by loaders, VMs and other riffraff. Just calculate the 32-bit address and write it down wherever you need it.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question