hi guys.
I was trying to do the first of the 2 example I found in this thread but
everytime I call VirtualProtect it returns false and GetLastError tells me 998 : "bad acces to the memory" (err...translated from swedish :grin: ).
Uhmm...it seems that the example is written for win95 maybe that's the problem, I'm on winXP.
Anyway I just copied the example straight off so I don't think I need to paste any code :)
If anyone can enlighten me, please do so :D

thanks a bunch
/edmund
Posted on 2003-07-06 15:37:35 by edmund
Hi edmund,
I use this typical setting on my Win98se (note that you may have another settings):

Code segment (selector CS):
Base=0, Limit FFFF_FFFF

Data segment, always writable (selector DS (DS=ES=SS):
Base=0, Limit 0000F5C0, bit ED (Expand Down)=1, that means accessible is range between limit+1...FFFF_FFFF

When I want to write to code, I use access through selector DS (always writable). Example:



00401000 3C01 CMP AL,1
00401002 7507 JNE SHORT 0040100B
00401004 C6050C104000 MOV BYTE PTR DS:[40100C],0
0040100B B301 MOV BL,1 ; AL=1: BL <- 0, AL<>1: BL<-1


Byte ptr [40100C] is accessible and writable in data segment so I may to write there through DS (or ES or SS)

Maybe it bring you some new idea.
Posted on 2003-07-06 18:04:19 by MazeGen
thanks for your reply MazeGen,
I've been searching the net for info on this and your
approach seems to be the common one (ie, writing the code to a data segment or
onto the stack ).

However, the example that I used seemed to modify the code segment.
Uhmm..just out of curiosity, can the code in the example execute on something
else than win95 (ie 98/2k/xp)?
I read in the win32.hlp file that VirtualProtect only succeed if the pages of
the specified region was allocated with VirtualAlloc, but yet the example states otherwise.
That makes me wonder if it's win95 specific ?

This is just out of pure curiousity, can you write to the code segment ?

thanks for your time :)

/edmund
Posted on 2003-07-06 19:00:19 by edmund
Well, I cannot answer a question about WinAPI and VirtualAlloc and so on, because I'm studying only instructions and PM at low-level, not OS level.

If you mean by question "can you write to the code segment?" to write through CS: prefix, I think it's impossible because code segment can be either executable or readable, never writable. But there is second level of translation linear address to physical address and it's paging (I don't know if that is the right word in english). Maybe there is possible with using paging to write to code through CS: prefix, but I don't think so.

I think we both have night, so happy dreams :)
Posted on 2003-07-06 19:53:28 by MazeGen
Hi

Try setting the protect flag to PAGE_EXECUTE_READWRITE instead. Could make a difference.

MazeGen: the descriptor that CS points to might typically not allow for writing, but far as I remember it can be changed to allow for it. Anyway, trying to modify code sections on winxp is best done using virtualprotect or virtualprotectex. Hacks that work on win9x typically don't work on xp, and shouldn't be relied upon.

Fake
Posted on 2003-07-07 06:37:33 by Fake51
hi Fake, thanks for you reply !
It doesn't matter what flag I set, I always get an error either way ( "ERROR_NOACCESS" in OlyDbg ).

Have you (or anyone else ) ever succeded in this quest ?
I've searched everywhere but still I can't seem to find anything
that says that this isn't doable on XP. All I've found were some examples
saying how it's supposed to be done but it doesn't work :(

thank you for your time :)

/edmund
Posted on 2003-07-07 08:48:17 by edmund

Try setting the protect flag to PAGE_EXECUTE_READWRITE instead. Could make a difference.

The PAGE_EXECUTE flag isn't implemented in Windows, actually. So you could jump to any address
and execute code there as long as you've got read permissions.

edmund, why don't you post some of your code?
Posted on 2003-07-07 11:12:34 by Tola

edmund, why don't you post some of your code?



hi guys.
I was trying to do the first of the 2 example I found in this thread
...
Anyway I just copied the example straight off so I don't think I need to paste any code :)

:)
Posted on 2003-07-07 11:14:12 by Delight

MazeGen: the descriptor that CS points to might typically not allow for writing, but far as I remember it can be changed to allow for it.
Fake


Thanks for you suggestion.

Small note that CS points always to instruction segment and there is no way how to allow this segment for writing (I'm speaking about writing through CS: prefix). See access rights belonging to instruction segment:



7 6 5 4 3 2 1 0 bit
P DPL 1 1 C R A


A-Accessed
R-Readable
C-Conforming
P-Segment present
DPL-Descriptor Privilege Level

You see, there is not present bit W-Writable (as in access rights belonging to data segment), which may allow writing. Instruction segment may be either executable or executable and readable.
Posted on 2003-07-07 14:12:28 by MazeGen
Hi and thanks for your answers ! :)

The PAGE_EXECUTE flag isn't implemented in Windows, actually. So you could jump to any address ...


I haven't had any problems reading code, I've only had problems writing it.
Is there another way besides VirtualProtect to enable the code segment for writing ?
In masm I could'n use VirtualProtect on any of the segments, I got "ACCESS_ERROR" all the time.

And as for the code, hehe thanks Delight for quoting me ;)
However, I made a simple masm example:



myProc proc blast:DWORD
mov eax,offset myMod2

push oldprotect
push PAGE_EXECUTE_READWRITE
push 4
push eax
call VirtualProtect

mov WORD PTR[eax],00B8h
mov WORD PTR[eax+1*2],0009h
mov WORD PTR[eax+2*2],0000h
mov WORD PTR[eax+3*2],0000h
mov WORD PTR[eax+4*2],0000h
call myMod2

ret
myProc ENDP


myMod2 proc
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
ret
myMod2 ENDP


dunno if that helps though :grin:

well, thanks a bunch!

/edmund :)
Posted on 2003-07-07 14:54:57 by edmund



Thanks for you suggestion.

Small note that CS points always to instruction segment and there is no way how to allow this segment for writing (I'm speaking about writing through CS: prefix). See access rights belonging to instruction segment:



7 6 5 4 3 2 1 0 bit
P DPL 1 1 C R A


A-Accessed
R-Readable
C-Conforming
P-Segment present
DPL-Descriptor Privilege Level

You see, there is not present bit W-Writable (as in access rights belonging to data segment), which may allow writing. Instruction segment may be either executable or executable and readable.


Read up on my protected mode docs. You're right, it's not possible to write to a segment with a descriptor for an executable segment.

Fake
Posted on 2003-07-07 17:12:25 by Fake51
Can't you just put the code you want to modify in the .idata section?
Posted on 2003-07-07 17:23:02 by Sephiroth3

Hi and thanks for your answers ! :)



I haven't had any problems reading code, I've only had problems writing it.
Is there another way besides VirtualProtect to enable the code segment for writing ?
In masm I could'n use VirtualProtect on any of the segments, I got "ACCESS_ERROR" all the time.

And as for the code, hehe thanks Delight for quoting me ;)
However, I made a simple masm example:



myProc proc blast:DWORD
mov eax,offset myMod2

push oldprotect
push PAGE_EXECUTE_READWRITE
push 4
push eax
call VirtualProtect

mov WORD PTR[eax],00B8h
mov WORD PTR[eax+1*2],0009h
mov WORD PTR[eax+2*2],0000h
mov WORD PTR[eax+3*2],0000h
mov WORD PTR[eax+4*2],0000h
call myMod2

ret
myProc ENDP


myMod2 proc
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
ret
myMod2 ENDP


dunno if that helps though :grin:

well, thanks a bunch!

/edmund :)


Just a thought, but

push oldprotect

pushes the wrong thing. Go with:

push offset oldprotect

Fake
Posted on 2003-07-07 17:36:44 by Fake51
take a look at yhis small example in PureBasic
http://purebasic.myforums.net/viewtopic.php?t=3650&highlight=selfmodifying+codeexample
it should be easy enough to follow.
Posted on 2003-07-07 17:38:44 by jack
Slightly modified version of your example. Works on my xp.

Fake



.486
.model flat, stdcall
option casemap:none

include e:\formerd\masm32\include\windows.inc
include e:\formerd\masm32\include\kernel32.inc
includelib e:\formerd\masm32\lib\kernel32.lib
include e:\formerd\masm32\include\user32.inc
includelib e:\formerd\masm32\lib\user32.lib

.data
oldprotect dd 0


.code
start:

mov eax,offset myMod2

invoke VirtualProtect,eax,4,PAGE_EXECUTE_READWRITE,addr oldprotect

mov eax,offset myMod2

mov WORD PTR[eax],00B8h
mov WORD PTR[eax+1*2],0009h
mov WORD PTR[eax+2*2],0000h
mov WORD PTR[eax+3*2],0000h
mov WORD PTR[eax+4*2],0000h

invoke ExitProcess,0
myMod2 proc
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
ret
myMod2 ENDP

end start
Posted on 2003-07-07 17:44:18 by Fake51
haha, I feel so stupid!!
thanks Fake, it works now!!! :grin: :grin:

thanks to everyone, I really appriciate it!! :)

/edmund :)
Posted on 2003-07-07 18:21:45 by edmund