Writing on code page?!?

I just finished an “interesting debugging experience” lasting over three
hours. The error was that a program wrote to an array with an index of
-26,000 or so. This happened to point to a position in the code page
and MODIFIED AN INSTRUCTION. This led to a mysterious fault at an
extremely remote point in the execution stream. Specifically, a
base/offset instruction was changed from base register ebp to ecx which
resolved to a negative address since ecx happened to contain 4 at the
time and the offset was -0x18.

I thought code pages are marked read-only. Is this not the case? In
fact, we were able to correct the instruction byte from 0x41 to 0x45 and
the program then happily ran. How did wd change an instruction byte?
Is there some compiler option I’m missing? Or what?

does your program use qnx_segment_* calls?

the ‘sin mem’ of your app will show that cs and ds are separate segments
pointing to same memory (depending on how you compile… but default is flat
so you will see this).
so we can put string literals and const in the cs …
the flags on these segments should indicate that cs is read/execute only.

but you can’t set an arbitrary pointer and crash into your cs… the
exception is if you use the qnx_segment_* calls which are powerful
beasts. watcom uses these to overlay and modify code/data… so does the
debugger.
if you haven’t used these calls then i am not sure how you could have
modified your code… maybe others have some thoughts. even if you munge
your cs and ds then you should get a segv before any corruption occurs.

Dean Douthat <ddouthat@faac.com> wrote:

I just finished an “interesting debugging experience” lasting over three
hours. The error was that a program wrote to an array with an index of
-26,000 or so. This happened to point to a position in the code page
and MODIFIED AN INSTRUCTION. This led to a mysterious fault at an
extremely remote point in the execution stream. Specifically, a
base/offset instruction was changed from base register ebp to ecx which
resolved to a negative address since ecx happened to contain 4 at the
time and the offset was -0x18.

I thought code pages are marked read-only. Is this not the case? In
fact, we were able to correct the instruction byte from 0x41 to 0x45 and
the program then happily ran. How did wd change an instruction byte?
Is there some compiler option I’m missing? Or what?


Randy Martin randy@qnx.com
Manager of FAE Group, North America
QNX Software Systems www.qnx.com
175 Terence Matthews Crescent, Kanata, Ontario, Canada K2M 1W8
Tel: 613-591-0931 Fax: 613-591-3579

Here’s a theory. This is a C++ program. Would an inline function have its
code on a data page? What if the class was instantiated by “new”?

Randy Martin wrote:

does your program use qnx_segment_* calls?

the ‘sin mem’ of your app will show that cs and ds are separate segments
pointing to same memory (depending on how you compile… but default is flat
so you will see this).
so we can put string literals and const in the cs …
the flags on these segments should indicate that cs is read/execute only.

but you can’t set an arbitrary pointer and crash into your cs… the
exception is if you use the qnx_segment_* calls which are powerful
beasts. watcom uses these to overlay and modify code/data… so does the
debugger.
if you haven’t used these calls then i am not sure how you could have
modified your code… maybe others have some thoughts. even if you munge
your cs and ds then you should get a segv before any corruption occurs.

Dean Douthat <> ddouthat@faac.com> > wrote:
I just finished an “interesting debugging experience” lasting over three
hours. The error was that a program wrote to an array with an index of
-26,000 or so. This happened to point to a position in the code page
and MODIFIED AN INSTRUCTION. This led to a mysterious fault at an
extremely remote point in the execution stream. Specifically, a
base/offset instruction was changed from base register ebp to ecx which
resolved to a negative address since ecx happened to contain 4 at the
time and the offset was -0x18.

I thought code pages are marked read-only. Is this not the case? In
fact, we were able to correct the instruction byte from 0x41 to 0x45 and
the program then happily ran. How did wd change an instruction byte?
Is there some compiler option I’m missing? Or what?


Randy Martin > randy@qnx.com
Manager of FAE Group, North America
QNX Software Systems > www.qnx.com
175 Terence Matthews Crescent, Kanata, Ontario, Canada K2M 1W8
Tel: 613-591-0931 Fax: 613-591-3579

Dean Douthat <ddouthat@faac.com> wrote:

Here’s a theory. This is a C++ program. Would an inline function have its
code on a data page? What if the class was instantiated by “new”?

a c++ person will need to answer this. but inlines as i have experienced
them will always assume a fixed ds (where ds = DGROUP).
and ds segment is not marked executable so you couldn’t execute it unless
you munged your page table (which is extremely unlikely unless you are privity
1 and you set far pointers direct to the correct segment of the pagedir)

Randy Martin wrote:

does your program use qnx_segment_* calls?

the ‘sin mem’ of your app will show that cs and ds are separate segments
pointing to same memory (depending on how you compile… but default is flat
so you will see this).
so we can put string literals and const in the cs …
the flags on these segments should indicate that cs is read/execute only.

but you can’t set an arbitrary pointer and crash into your cs… the
exception is if you use the qnx_segment_* calls which are powerful
beasts. watcom uses these to overlay and modify code/data… so does the
debugger.
if you haven’t used these calls then i am not sure how you could have
modified your code… maybe others have some thoughts. even if you munge
your cs and ds then you should get a segv before any corruption occurs.

Dean Douthat <> ddouthat@faac.com> > wrote:
I just finished an “interesting debugging experience” lasting over three
hours. The error was that a program wrote to an array with an index of
-26,000 or so. This happened to point to a position in the code page
and MODIFIED AN INSTRUCTION. This led to a mysterious fault at an
extremely remote point in the execution stream. Specifically, a
base/offset instruction was changed from base register ebp to ecx which
resolved to a negative address since ecx happened to contain 4 at the
time and the offset was -0x18.

I thought code pages are marked read-only. Is this not the case? In
fact, we were able to correct the instruction byte from 0x41 to 0x45 and
the program then happily ran. How did wd change an instruction byte?
Is there some compiler option I’m missing? Or what?


Randy Martin > randy@qnx.com
Manager of FAE Group, North America
QNX Software Systems > www.qnx.com
175 Terence Matthews Crescent, Kanata, Ontario, Canada K2M 1W8
Tel: 613-591-0931 Fax: 613-591-3579


Randy Martin randy@qnx.com
Manager of FAE Group, North America
QNX Software Systems www.qnx.com
175 Terence Matthews Crescent, Kanata, Ontario, Canada K2M 1W8
Tel: 613-591-0931 Fax: 613-591-3579

Surely the debugger can write to code pages (otherwise it’d be a
pretty useless debugger wouldn’t it ? :slight_smile:. Are you sure, that it
wasn’t something you did in the debugger that caused the initial
write to the code page in the first place ?

I would be extremely interested if you could produce a test case
that can successfully write to the code page (without explicitly
changing the permissions on the page of course).

-----Original Message-----
From: Dean Douthat [mailto:ddouthat@faac.com]
Posted At: Tuesday, February 27, 2001 2:10 PM
Posted To: qnx4
Conversation: Writing on code page?!?
Subject: Writing on code page?!?


I just finished an “interesting debugging experience” lasting over three
hours. The error was that a program wrote to an array with an index of
-26,000 or so. This happened to point to a position in the code page
and MODIFIED AN INSTRUCTION. This led to a mysterious fault at an
extremely remote point in the execution stream. Specifically, a
base/offset instruction was changed from base register ebp to ecx which
resolved to a negative address since ecx happened to contain 4 at the
time and the offset was -0x18.

I thought code pages are marked read-only. Is this not the case? In
fact, we were able to correct the instruction byte from 0x41 to 0x45 and
the program then happily ran. How did wd change an instruction byte?
Is there some compiler option I’m missing? Or what?

Yes, the debugger should be able to write on the code page. But, I hope, it
does so by changing page attribute, doing the write, changing attribute
back. My question was if it did something else (or the code page was not
read-only in the first place if, for example, -g is used during
compile/link.

I have an example where code is being changed. I’m not necessarily sure
this code is actually on the code page (see discussion of C++ inline
functions earlier in this thread).

Rennie Allen wrote:

Surely the debugger can write to code pages (otherwise it’d be a
pretty useless debugger wouldn’t it ? > :slight_smile:> . Are you sure, that it
wasn’t something you did in the debugger that caused the initial
write to the code page in the first place ?

I would be extremely interested if you could produce a test case
that can successfully write to the code page (without explicitly
changing the permissions on the page of course).

-----Original Message-----
From: Dean Douthat [mailto:> ddouthat@faac.com> ]
Posted At: Tuesday, February 27, 2001 2:10 PM
Posted To: qnx4
Conversation: Writing on code page?!?
Subject: Writing on code page?!?

I just finished an “interesting debugging experience” lasting over three
hours. The error was that a program wrote to an array with an index of
-26,000 or so. This happened to point to a position in the code page
and MODIFIED AN INSTRUCTION. This led to a mysterious fault at an
extremely remote point in the execution stream. Specifically, a
base/offset instruction was changed from base register ebp to ecx which
resolved to a negative address since ecx happened to contain 4 at the
time and the offset was -0x18.

I thought code pages are marked read-only. Is this not the case? In
fact, we were able to correct the instruction byte from 0x41 to 0x45 and
the program then happily ran. How did wd change an instruction byte?
Is there some compiler option I’m missing? Or what?

Any C++ or other QSSL person who would like to venture an opinion on this?

Randy Martin wrote:

Dean Douthat <> ddouthat@faac.com> > wrote:
Here’s a theory. This is a C++ program. Would an inline function have its
code on a data page? What if the class was instantiated by “new”?

a c++ person will need to answer this. but inlines as i have experienced
them will always assume a fixed ds (where ds = DGROUP).
and ds segment is not marked executable so you couldn’t execute it unless
you munged your page table (which is extremely unlikely unless you are privity
1 and you set far pointers direct to the correct segment of the pagedir)

Randy Martin wrote:

does your program use qnx_segment_* calls?

the ‘sin mem’ of your app will show that cs and ds are separate segments
pointing to same memory (depending on how you compile… but default is flat
so you will see this).
so we can put string literals and const in the cs …
the flags on these segments should indicate that cs is read/execute only.

but you can’t set an arbitrary pointer and crash into your cs… the
exception is if you use the qnx_segment_* calls which are powerful
beasts. watcom uses these to overlay and modify code/data… so does the
debugger.
if you haven’t used these calls then i am not sure how you could have
modified your code… maybe others have some thoughts. even if you munge
your cs and ds then you should get a segv before any corruption occurs.

Dean Douthat <> ddouthat@faac.com> > wrote:
I just finished an “interesting debugging experience” lasting over three
hours. The error was that a program wrote to an array with an index of
-26,000 or so. This happened to point to a position in the code page
and MODIFIED AN INSTRUCTION. This led to a mysterious fault at an
extremely remote point in the execution stream. Specifically, a
base/offset instruction was changed from base register ebp to ecx which
resolved to a negative address since ecx happened to contain 4 at the
time and the offset was -0x18.

I thought code pages are marked read-only. Is this not the case? In
fact, we were able to correct the instruction byte from 0x41 to 0x45 and
the program then happily ran. How did wd change an instruction byte?
Is there some compiler option I’m missing? Or what?


Randy Martin > randy@qnx.com
Manager of FAE Group, North America
QNX Software Systems > www.qnx.com
175 Terence Matthews Crescent, Kanata, Ontario, Canada K2M 1W8
Tel: 613-591-0931 Fax: 613-591-3579


Randy Martin > randy@qnx.com
Manager of FAE Group, North America
QNX Software Systems > www.qnx.com
175 Terence Matthews Crescent, Kanata, Ontario, Canada K2M 1W8
Tel: 613-591-0931 Fax: 613-591-3579