Execution of Dynamically Generated code.

Hello All,
My driver generates some code at run time ,I want to execute it from
driver and application too.
I have allocated page for it which is accessible from user and kernel.
From user app. how can I execute that page ?

Thanx…

First: I can’t see any reason, why you want to make the same code available
to Ring3 and Ring0!!! It does somehow sound like Spaghetti-design.

Second: In the Segment Descriptor, Type fields must be set to CODE and not
DATA (with other words PAGES must have executable protection). In PDEs and
PTEs if the Supervisor flag is set, the pages can be only accessed in Ring0.
(If you have an MDL or Section and maps it into a Process Address space, the
problem with Supervisor is solved; it also solves the problem with DPL field
of Segment Descriptor)

Third: Your code must be self-relative. You can’t use direct addresses to
acccess data (because the same code is going to run in Ring3 and kernel
address space is not accessible from Ring3==>GP#).

Fourth: Don’t use any privilleged instructions in your code

Last: I am really interested to know (If you can say) why the same code
should run in Ring0 and Ring3)

Johnny

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of TheDonx
Sent: Freitag, 3. Mai 2002 06:24
To: NT Developers Interest List
Subject: [ntdev] Execution of Dynamically Generated code.

Hello All,
My driver generates some code at run time ,I want to execute it from
driver and application too.
I have allocated page for it which is accessible from user and kernel.
From user app. how can I execute that page ?

Thanx…


You are currently subscribed to ntdev as: xxxxx@yahoo.de
To unsubscribe send a blank email to %%email.unsub%%


Do You Yahoo!?

Get your free @yahoo.com address at http://mail.yahoo.com

Oh I forgot:

Fifth: If every thing is OK, just make a call to your code or jump into it
(if you jump, see how you can go back to calling code)

__asm {
push eax
mov eax, variable which contains code address

//if you want to call the code
//push your arguments on stack if any

call eax
pop eax

//or if you want to jump
//save your return address into a register, save all used registers on
stack
//load your arguments into registers
jmp eax
pop eax
//pop out all saved register
}

in your selfcreated code,

if it is called used ret n (n= byte count of arguments)

or if you jumped, just jump back to your return address, which you saved
into a register and pop out saved register from stack after jumping back

On other point: take care about which calling convention you use, because
eax is normally used for returning results and similar for other registers
used

Johnny

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Johnny
Sent: Freitag, 3. Mai 2002 14:08
To: NT Developers Interest List
Subject: [ntdev] RE: Execution of Dynamically Generated code.

First: I can’t see any reason, why you want to make the same code available
to Ring3 and Ring0!!! It does somehow sound like Spaghetti-design.

Second: In the Segment Descriptor, Type fields must be set to CODE and not
DATA (with other words PAGES must have executable protection). In PDEs and
PTEs if the Supervisor flag is set, the pages can be only accessed in Ring0.
(If you have an MDL or Section and maps it into a Process Address space, the
problem with Supervisor is solved; it also solves the problem with DPL field
of Segment Descriptor)

Third: Your code must be self-relative. You can’t use direct addresses to
acccess data (because the same code is going to run in Ring3 and kernel
address space is not accessible from Ring3==>GP#).

Fourth: Don’t use any privilleged instructions in your code

Last: I am really interested to know (If you can say) why the same code
should run in Ring0 and Ring3)

Johnny

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of TheDonx
Sent: Freitag, 3. Mai 2002 06:24
To: NT Developers Interest List
Subject: [ntdev] Execution of Dynamically Generated code.

Hello All,
My driver generates some code at run time ,I want to execute it from
driver and application too.
I have allocated page for it which is accessible from user and kernel.
From user app. how can I execute that page ?

Thanx…


You are currently subscribed to ntdev as: xxxxx@yahoo.de
To unsubscribe send a blank email to %%email.unsub%%


Do You Yahoo!?

Get your free @yahoo.com address at http://mail.yahoo.com


You are currently subscribed to ntdev as: xxxxx@yahoo.de
To unsubscribe send a blank email to %%email.unsub%%


Do You Yahoo!?

Get your free @yahoo.com address at http://mail.yahoo.com

Hi, Bounce,

Generating code on the fly is a time-honored technique. Before
graphics chips had all 256 rops in hardware, for example, the
Microsoft DDK sample for the IBM 8514 generated code to do a rop-
bitblt on the fly, on the stack, then wrapped it in a segment, turned
on the execute bit, and did a far call to it. This generated code that
was by far faster than any kind of static code one could generate,
unless of course we stopped to code all 256 rops by hand.

You have to learn how to use your segments, and how to set one
up ! I’m not sure the OS lets you do that kind of thing today, so you
may be on your own: read the Intel architecture book and learn how
to set up a new entry in your LDT. Generate your code, set up your
LDT entry, do a far call, wipe out your LDT entry, and collapse the
buffer. The worse that can happen is - and here’s the heretic
speaking again - is you having to tuck away the current LDT, set
up your own LDT and your own segment descriptor by hand,
instate your own LDT, far call your code, then reinstate the old
LDT. That can be done pretty fast too, if you take the appropriate
care, but it’s precise code, for grown ups to generate and maintain.

Are you sure you want to do that ?

Alberto.

==========================

On 3 May 2002, at 14:08, Johnny wrote:

First: I can’t see any reason, why you want to make the same code available
to Ring3 and Ring0!!! It does somehow sound like Spaghetti-design.

Second: In the Segment Descriptor, Type fields must be set to CODE and not
DATA (with other words PAGES must have executable protection). In PDEs and
PTEs if the Supervisor flag is set, the pages can be only accessed in Ring0.
(If you have an MDL or Section and maps it into a Process Address space, the
problem with Supervisor is solved; it also solves the problem with DPL field
of Segment Descriptor)

Third: Your code must be self-relative. You can’t use direct addresses to
acccess data (because the same code is going to run in Ring3 and kernel
address space is not accessible from Ring3==>GP#).

Fourth: Don’t use any privilleged instructions in your code

Last: I am really interested to know (If you can say) why the same code
should run in Ring0 and Ring3)

Johnny

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of TheDonx
Sent: Freitag, 3. Mai 2002 06:24
To: NT Developers Interest List
Subject: [ntdev] Execution of Dynamically Generated code.

Hello All,
My driver generates some code at run time ,I want to execute it from
driver and application too.
I have allocated page for it which is accessible from user and kernel.
>From user app. how can I execute that page ?

Thanx…


You are currently subscribed to ntdev as: xxxxx@yahoo.de
To unsubscribe send a blank email to %%email.unsub%%


Do You Yahoo!?

Get your free @yahoo.com address at http://mail.yahoo.com


You are currently subscribed to ntdev as: xxxxx@ieee.org
To unsubscribe send a blank email to %%email.unsub%%

Of course you can access data directly if you get the address from code
which calls the self created code

Johnny

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of Johnny
Sent: Freitag, 3. Mai 2002 14:08
To: NT Developers Interest List
Subject: [ntdev] RE: Execution of Dynamically Generated code.

First: I can’t see any reason, why you want to make the same code available
to Ring3 and Ring0!!! It does somehow sound like Spaghetti-design.

Second: In the Segment Descriptor, Type fields must be set to CODE and not
DATA (with other words PAGES must have executable protection). In PDEs and
PTEs if the Supervisor flag is set, the pages can be only accessed in Ring0.
(If you have an MDL or Section and maps it into a Process Address space, the
problem with Supervisor is solved; it also solves the problem with DPL field
of Segment Descriptor)

Third: Your code must be self-relative. You can’t use direct addresses to
acccess data (because the same code is going to run in Ring3 and kernel
address space is not accessible from Ring3==>GP#).

Fourth: Don’t use any privilleged instructions in your code

Last: I am really interested to know (If you can say) why the same code
should run in Ring0 and Ring3)

Johnny

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com]On Behalf Of TheDonx
Sent: Freitag, 3. Mai 2002 06:24
To: NT Developers Interest List
Subject: [ntdev] Execution of Dynamically Generated code.

Hello All,
My driver generates some code at run time ,I want to execute it from
driver and application too.
I have allocated page for it which is accessible from user and kernel.
From user app. how can I execute that page ?

Thanx…


You are currently subscribed to ntdev as: xxxxx@yahoo.de
To unsubscribe send a blank email to %%email.unsub%%


Do You Yahoo!?

Get your free @yahoo.com address at http://mail.yahoo.com


You are currently subscribed to ntdev as: xxxxx@yahoo.de
To unsubscribe send a blank email to %%email.unsub%%


Do You Yahoo!?

Get your free @yahoo.com address at http://mail.yahoo.com

Make a dummy call to get an EIP and push into stack before calling the
buffer code, so that “ret” will work to come back.

----- Original Message -----
From: “Johnny”
To: “NT Developers Interest List”
Sent: Friday, May 03, 2002 6:13 PM
Subject: [ntdev] RE: Execution of Dynamically Generated code.

> Oh I forgot:
>
> Fifth: If every thing is OK, just make a call to your code or jump into it
> (if you jump, see how you can go back to calling code)
>
> asm {
> push eax
> mov eax, variable which contains code address
>
> //if you want to call the code
> //push your arguments on stack if any
>
> call eax
> pop eax
>
> //or if you want to jump
> //save your return address into a register, save all used registers on
> stack
> //load your arguments into registers
> jmp eax
> pop eax
> //pop out all saved register
> }
>
> in your selfcreated code,
>
> if it is called used ret n (n= byte count of arguments)
>
> or if you jumped, just jump back to your return address, which you saved
> into a register and pop out saved register from stack after jumping back
>
> On other point: take care about which calling convention you use, because
> eax is normally used for returning results and similar for other registers
> used
>
> Johnny
>
>
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]On Behalf Of Johnny
> Sent: Freitag, 3. Mai 2002 14:08
> To: NT Developers Interest List
> Subject: [ntdev] RE: Execution of Dynamically Generated code.
>
>
> First: I can’t see any reason, why you want to make the same code
available
> to Ring3 and Ring0!!! It does somehow sound like Spaghetti-design.
>
> Second: In the Segment Descriptor, Type fields must be set to CODE and not
> DATA (with other words PAGES must have executable protection). In PDEs and
> PTEs if the Supervisor flag is set, the pages can be only accessed in
Ring0.
> (If you have an MDL or Section and maps it into a Process Address space,
the
> problem with Supervisor is solved; it also solves the problem with DPL
field
> of Segment Descriptor)
>
> Third: Your code must be self-relative. You can’t use direct addresses to
> acccess data (because the same code is going to run in Ring3 and kernel
> address space is not accessible from Ring3==>GP#).
>
> Fourth: Don’t use any privilleged instructions in your code
>
> Last: I am really interested to know (If you can say) why the same code
> should run in Ring0 and Ring3)
>
>
> Johnny
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com]On Behalf Of TheDonx
> Sent: Freitag, 3. Mai 2002 06:24
> To: NT Developers Interest List
> Subject: [ntdev] Execution of Dynamically Generated code.
>
>
> Hello All,
> My driver generates some code at run time ,I want to execute it from
> driver and application too.
> I have allocated page for it which is accessible from user and kernel.
> From user app. how can I execute that page ?
>
> Thanx…
>
> —
> You are currently subscribed to ntdev as: xxxxx@yahoo.de
> To unsubscribe send a blank email to %%email.unsub%%
>
>
>
>
_______________________________________________________
>
> Do You Yahoo!?
>
> Get your free @yahoo.com address at http://mail.yahoo.com
>
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@yahoo.de
> To unsubscribe send a blank email to %%email.unsub%%
>
>
>
> _________________________________________________________
>
> Do You Yahoo!?
>
> Get your free @yahoo.com address at http://mail.yahoo.com
>
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@aalayance.com
> To unsubscribe send a blank email to %%email.unsub%%
>



Alberto,

Sorry dude, but I have been around the computer stack a few times … and
this practice was never “time-honored”. It was always considered a “last
resort” “ain’t no other way” “error prone piece of crap”. Which it genuinely
is. The only engineers I have ever seen that considered it “time-honored”
were the ones that had no life outside a keyboard and thought it a way to
ensure their paycheck because no one else was smart enough to figure how
they did this “magic”. Have I used this programming gimmick? Having started
in '74, of course I have, until computers and memory improved and I found a
better way. It is a classic “hack” … invoking the same religious fervor as
“goto” or not “goto”. The only place I would expect to see such code is that
brief interval when all of memory is being tested aftera power on. Using it
in a driver/application interface is an attempt to side step proper
implementation of a device driver, because the company is to cheap to do it
right, or the engineer is still in his “cute programming phase”.

Personally, I would invoke Greg Dyess’s injunction: “If this is a
commercially produced driver, please let me know the product name so I can
avoid wasting time with it.”

falls down the stairs.>

Gary G. Little
xxxxx@broadstor.com
xxxxx@inland.net

wrote in message news:xxxxx@ntdev…
>
> Hi, Bounce,
>
> Generating code on the fly is a time-honored technique. Before
> graphics chips had all 256 rops in hardware, for example, the
> Microsoft DDK sample for the IBM 8514 generated code to do a rop-
> bitblt on the fly, on the stack, then wrapped it in a segment, turned
> on the execute bit, and did a far call to it. This generated code that
> was by far faster than any kind of static code one could generate,
> unless of course we stopped to code all 256 rops by hand.
>
> You have to learn how to use your segments, and how to set one
> up ! I’m not sure the OS lets you do that kind of thing today, so you
> may be on your own: read the Intel architecture book and learn how
> to set up a new entry in your LDT. Generate your code, set up your
> LDT entry, do a far call, wipe out your LDT entry, and collapse the
> buffer. The worse that can happen is - and here’s the heretic
> speaking again - is you having to tuck away the current LDT, set
> up your own LDT and your own segment descriptor by hand,
> instate your own LDT, far call your code, then reinstate the old
> LDT. That can be done pretty fast too, if you take the appropriate
> care, but it’s precise code, for grown ups to generate and maintain.
>
> Are you sure you want to do that ?
>
>
> Alberto.
>
> ==========================
>
> On 3 May 2002, at 14:08, Johnny wrote:
>
> > First: I can’t see any reason, why you want to make the same code
available
> > to Ring3 and Ring0!!! It does somehow sound like Spaghetti-design.
> >
> > Second: In the Segment Descriptor, Type fields must be set to CODE and
not
> > DATA (with other words PAGES must have executable protection). In PDEs
and
> > PTEs if the Supervisor flag is set, the pages can be only accessed in
Ring0.
> > (If you have an MDL or Section and maps it into a Process Address space,
the
> > problem with Supervisor is solved; it also solves the problem with DPL
field
> > of Segment Descriptor)
> >
> > Third: Your code must be self-relative. You can’t use direct addresses
to
> > acccess data (because the same code is going to run in Ring3 and kernel
> > address space is not accessible from Ring3==>GP#).
> >
> > Fourth: Don’t use any privilleged instructions in your code
> >
> > Last: I am really interested to know (If you can say) why the same code
> > should run in Ring0 and Ring3)
> >
> >
> > Johnny
> >
> >
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com]On Behalf Of TheDonx
> > Sent: Freitag, 3. Mai 2002 06:24
> > To: NT Developers Interest List
> > Subject: [ntdev] Execution of Dynamically Generated code.
> >
> >
> > Hello All,
> > My driver generates some code at run time ,I want to execute it from
> > driver and application too.
> > I have allocated page for it which is accessible from user and kernel.
> > >From user app. how can I execute that page ?
> >
> > Thanx…
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@yahoo.de
> > To unsubscribe send a blank email to %%email.unsub%%
> >
> >
> >
> > _________________________________________________________
> >
> > Do You Yahoo!?
> >
> > Get your free @yahoo.com address at http://mail.yahoo.com
> >
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@ieee.org
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
>
>

For a long time there was no other way to get more throughput from a Bitblt.
Call it what you want, it’s been with us ever since the days of Win31, and
it didn’t change until people put all 256 rops in hardware.

So, what’s “right” ? If all I did was what Microsoft says its right, I’d
probably not have shipped any product in the past 15 years or so.

Alberto.

==========================================

-----Original Message-----
From: Gary G. Little [mailto:xxxxx@broadstor.com]
Sent: Monday, May 06, 2002 12:55 PM
To: NT Developers Interest List
Subject: [ntdev] Re: Execution of Dynamically Generated code.



Alberto,

Sorry dude, but I have been around the computer stack a few times … and
this practice was never “time-honored”. It was always considered a “last
resort” “ain’t no other way” “error prone piece of crap”. Which it genuinely
is. The only engineers I have ever seen that considered it “time-honored”
were the ones that had no life outside a keyboard and thought it a way to
ensure their paycheck because no one else was smart enough to figure how
they did this “magic”. Have I used this programming gimmick? Having started
in '74, of course I have, until computers and memory improved and I found a
better way. It is a classic “hack” … invoking the same religious fervor as
“goto” or not “goto”. The only place I would expect to see such code is that
brief interval when all of memory is being tested aftera power on. Using it
in a driver/application interface is an attempt to side step proper
implementation of a device driver, because the company is to cheap to do it
right, or the engineer is still in his “cute programming phase”.

Personally, I would invoke Greg Dyess’s injunction: “If this is a
commercially produced driver, please let me know the product name so I can
avoid wasting time with it.”

falls down the stairs.>

Gary G. Little
xxxxx@broadstor.com
xxxxx@inland.net

wrote in message news:xxxxx@ntdev…
>
> Hi, Bounce,
>
> Generating code on the fly is a time-honored technique. Before
> graphics chips had all 256 rops in hardware, for example, the
> Microsoft DDK sample for the IBM 8514 generated code to do a rop-
> bitblt on the fly, on the stack, then wrapped it in a segment, turned
> on the execute bit, and did a far call to it. This generated code that
> was by far faster than any kind of static code one could generate,
> unless of course we stopped to code all 256 rops by hand.
>
> You have to learn how to use your segments, and how to set one
> up ! I’m not sure the OS lets you do that kind of thing today, so you
> may be on your own: read the Intel architecture book and learn how
> to set up a new entry in your LDT. Generate your code, set up your
> LDT entry, do a far call, wipe out your LDT entry, and collapse the
> buffer. The worse that can happen is - and here’s the heretic
> speaking again - is you having to tuck away the current LDT, set
> up your own LDT and your own segment descriptor by hand,
> instate your own LDT, far call your code, then reinstate the old
> LDT. That can be done pretty fast too, if you take the appropriate
> care, but it’s precise code, for grown ups to generate and maintain.
>
> Are you sure you want to do that ?
>
>
> Alberto.
>
> ==========================
>
> On 3 May 2002, at 14:08, Johnny wrote:
>
> > First: I can’t see any reason, why you want to make the same code
available
> > to Ring3 and Ring0!!! It does somehow sound like Spaghetti-design.
> >
> > Second: In the Segment Descriptor, Type fields must be set to CODE and
not
> > DATA (with other words PAGES must have executable protection). In PDEs
and
> > PTEs if the Supervisor flag is set, the pages can be only accessed in
Ring0.
> > (If you have an MDL or Section and maps it into a Process Address space,
the
> > problem with Supervisor is solved; it also solves the problem with DPL
field
> > of Segment Descriptor)
> >
> > Third: Your code must be self-relative. You can’t use direct addresses
to
> > acccess data (because the same code is going to run in Ring3 and kernel
> > address space is not accessible from Ring3==>GP#).
> >
> > Fourth: Don’t use any privilleged instructions in your code
> >
> > Last: I am really interested to know (If you can say) why the same code
> > should run in Ring0 and Ring3)
> >
> >
> > Johnny
> >
> >
> > -----Original Message-----
> > From: xxxxx@lists.osr.com
> > [mailto:xxxxx@lists.osr.com]On Behalf Of TheDonx
> > Sent: Freitag, 3. Mai 2002 06:24
> > To: NT Developers Interest List
> > Subject: [ntdev] Execution of Dynamically Generated code.
> >
> >
> > Hello All,
> > My driver generates some code at run time ,I want to execute it from
> > driver and application too.
> > I have allocated page for it which is accessible from user and kernel.
> > >From user app. how can I execute that page ?
> >
> > Thanx…
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@yahoo.de
> > To unsubscribe send a blank email to %%email.unsub%%
> >
> >
> >
> > _________________________________________________________
> >
> > Do You Yahoo!?
> >
> > Get your free @yahoo.com address at http://mail.yahoo.com
> >
> >
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@ieee.org
> > To unsubscribe send a blank email to %%email.unsub%%
> >
>
>
>
>


You are currently subscribed to ntdev as: xxxxx@compuware.com
To unsubscribe send a blank email to %%email.unsub%%

The contents of this e-mail are intended for the named addressee only. It
contains information that may be confidential. Unless you are the named
addressee or an authorized designee, you may not copy or use it, or disclose
it to anyone else. If you received it in error please notify us immediately
and then destroy it.

> > Generating code on the fly is a time-honored technique.

Sorry dude, but I have been around the computer stack a few times … and
this practice was never “time-honored”. It was always considered a “last
resort” “ain’t no other way” “error prone piece of crap”.

I’m going to have to agree with Alberto here, that dynamic generation of
code is an accepted technique in computer science. It’s very appropriate to
defer the code generation phase of an algorithm until run-time under some
conditions. After all, code is really just data to a compiler. I have no
problem reducing the time between compiling code and running code to
milliseconds.

A few quick examples, html is clearly data to a web server, and can be very
much code in your browser, and is very often dynamically generated.
Postscript is in the same category.

I believe Windows 2.x used dynamically generated code “thunks”, created by
MakeProcInstance. WIndows 3.x I believe dynamically patched VxD system
service interrupts with call instructions, and used dynamic code thunks for
a variety of things. Environments like Java and .NET dynamically generate
local machine code from platform independent instruction sets. The Java
hotspot compiler will not only dynamically generate code, it will
dynamically profile code and dynamically generate more optimal code as your
program runs (this was originally done by the Self language team at
Stanford and then Sun). Many debugger’s implement code breakpoints by
dynamically inserting breakpoint instructions in the memory space of the
target code.

Many systems DON’T use position independent code, including typical code on
x86 machines running 32-bit Windows. Code get’s dynamically patched at
load-time (moments before run-time) to fixup global variable addresses and
function calls. It would architecturally be possible to have code on x86
systems that did NOT get fixed up at load-time and was position
independent, but dynamically patching things gives better performance.

Offhand, dynamic generation and patching of code seems pretty widely used
in the Windows universe. I’d agree that on some embedded processors, code
and data are unquestionably separate. This does have the nice advantage
that it’s impossible for buggy code or data to ever damage the code. If
course if your embedded system has flash memory and the code is capable of
writing into flash, then it seems like this hard separation between code
and data get’s a little fuzzier.

I do believe that most of the tools we use (I.e. debuggers) are not so good
at using code metadata that’s dynamically generated and is stored in the
executing program memory. Prototype based languages (Self for example), can
not only have “code” dynamically show up, but the structure of live objects
can be changed dynamically. For you C programmers this would be the
equivalent of a function dynamically deciding it needed another field in a
structure, so added it as the program ran.

I’d suggest it can be MUCH easier to design a piece of code that
dynamically generates code than to design a piece of code that supplies the
same functionality. My quick example, it’s much easier to design a compiler
than to design a program that can implement any code you might compile.

  • Jan

I am sure, Original guy has lost in this discussion :wink:

----- Original Message -----
From: “Jan Bottorff”
To: “NT Developers Interest List”
Sent: Tuesday, May 07, 2002 12:20 PM
Subject: [ntdev] Re: Execution of Dynamically Generated code.

>
> > > Generating code on the fly is a time-honored technique.
> >
> >Sorry dude, but I have been around the computer stack a few times … and
> >this practice was never “time-honored”. It was always considered a “last
> >resort” “ain’t no other way” “error prone piece of crap”.
>
> I’m going to have to agree with Alberto here, that dynamic generation of
> code is an accepted technique in computer science. It’s very appropriate
to
> defer the code generation phase of an algorithm until run-time under some
> conditions. After all, code is really just data to a compiler. I have no
> problem reducing the time between compiling code and running code to
> milliseconds.
>
> A few quick examples, html is clearly data to a web server, and can be
very
> much code in your browser, and is very often dynamically generated.
> Postscript is in the same category.
>
> I believe Windows 2.x used dynamically generated code “thunks”, created by
> MakeProcInstance. WIndows 3.x I believe dynamically patched VxD system
> service interrupts with call instructions, and used dynamic code thunks
for
> a variety of things. Environments like Java and .NET dynamically generate
> local machine code from platform independent instruction sets. The Java
> hotspot compiler will not only dynamically generate code, it will
> dynamically profile code and dynamically generate more optimal code as
your
> program runs (this was originally done by the Self language team at
> Stanford and then Sun). Many debugger’s implement code breakpoints by
> dynamically inserting breakpoint instructions in the memory space of the
> target code.
>
> Many systems DON’T use position independent code, including typical code
on
> x86 machines running 32-bit Windows. Code get’s dynamically patched at
> load-time (moments before run-time) to fixup global variable addresses and
> function calls. It would architecturally be possible to have code on x86
> systems that did NOT get fixed up at load-time and was position
> independent, but dynamically patching things gives better performance.
>
> Offhand, dynamic generation and patching of code seems pretty widely used
> in the Windows universe. I’d agree that on some embedded processors, code
> and data are unquestionably separate. This does have the nice advantage
> that it’s impossible for buggy code or data to ever damage the code. If
> course if your embedded system has flash memory and the code is capable of
> writing into flash, then it seems like this hard separation between code
> and data get’s a little fuzzier.
>
> I do believe that most of the tools we use (I.e. debuggers) are not so
good
> at using code metadata that’s dynamically generated and is stored in the
> executing program memory. Prototype based languages (Self for example),
can
> not only have “code” dynamically show up, but the structure of live
objects
> can be changed dynamically. For you C programmers this would be the
> equivalent of a function dynamically deciding it needed another field in a
> structure, so added it as the program ran.
>
> I’d suggest it can be MUCH easier to design a piece of code that
> dynamically generates code than to design a piece of code that supplies
the
> same functionality. My quick example, it’s much easier to design a
compiler
> than to design a program that can implement any code you might compile.
>
> - Jan
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@aalayance.com
> To unsubscribe send a blank email to %%email.unsub%%
>

Jan,

Thanks for the html example ! Actually, that’s how ASP works, no
? The server generates a source HTML program that is sent down
to the client to be interpreted there.

Alberto.

On 6 May 2002, at 23:50, Jan Bottorff wrote:

> > Generating code on the fly is a time-honored technique.
>
>Sorry dude, but I have been around the computer stack a few times … and
>this practice was never “time-honored”. It was always considered a “last
>resort” “ain’t no other way” “error prone piece of crap”.

I’m going to have to agree with Alberto here, that dynamic generation of
code is an accepted technique in computer science. It’s very appropriate to
defer the code generation phase of an algorithm until run-time under some
conditions. After all, code is really just data to a compiler. I have no
problem reducing the time between compiling code and running code to
milliseconds.

A few quick examples, html is clearly data to a web server, and can be very
much code in your browser, and is very often dynamically generated.
Postscript is in the same category.

I believe Windows 2.x used dynamically generated code “thunks”, created by
MakeProcInstance. WIndows 3.x I believe dynamically patched VxD system
service interrupts with call instructions, and used dynamic code thunks for
a variety of things. Environments like Java and .NET dynamically generate
local machine code from platform independent instruction sets. The Java
hotspot compiler will not only dynamically generate code, it will
dynamically profile code and dynamically generate more optimal code as your
program runs (this was originally done by the Self language team at
Stanford and then Sun). Many debugger’s implement code breakpoints by
dynamically inserting breakpoint instructions in the memory space of the
target code.

Many systems DON’T use position independent code, including typical code on
x86 machines running 32-bit Windows. Code get’s dynamically patched at
load-time (moments before run-time) to fixup global variable addresses and
function calls. It would architecturally be possible to have code on x86
systems that did NOT get fixed up at load-time and was position
independent, but dynamically patching things gives better performance.

Offhand, dynamic generation and patching of code seems pretty widely used
in the Windows universe. I’d agree that on some embedded processors, code
and data are unquestionably separate. This does have the nice advantage
that it’s impossible for buggy code or data to ever damage the code. If
course if your embedded system has flash memory and the code is capable of
writing into flash, then it seems like this hard separation between code
and data get’s a little fuzzier.

I do believe that most of the tools we use (I.e. debuggers) are not so good
at using code metadata that’s dynamically generated and is stored in the
executing program memory. Prototype based languages (Self for example), can
not only have “code” dynamically show up, but the structure of live objects
can be changed dynamically. For you C programmers this would be the
equivalent of a function dynamically deciding it needed another field in a
structure, so added it as the program ran.

I’d suggest it can be MUCH easier to design a piece of code that
dynamically generates code than to design a piece of code that supplies the
same functionality. My quick example, it’s much easier to design a compiler
than to design a program that can implement any code you might compile.

  • Jan

You are currently subscribed to ntdev as: xxxxx@ieee.org
To unsubscribe send a blank email to %%email.unsub%%

OpenGL generates machine code dynamically and executes it.

“Last resort”? In the case of OpenGL, the “last resort” is to NOT
dynamically generate machine code.

“Error prone”? Not at all. Mapping the logical operations to machine code
is very straightforward. Sophisticated in the design and programming, yes.
Error-prone? Only while the code generator was being developed.

“Piece of crap”? OpenGL is a very, very impressive piece of work!! I am
honored to have spent time in the actual OpenGL source base. The dynamic
generation of machine code is key to its performance.

“Aint’ no other way”? OpenGL, when compiled for platforms that the machine
code generator does not support, uses pre-compiled C functions, but it is
much slower on those platforms.

From what I heard, the DirectX programmers at Microsoft could not figure out
how OpenGL was so amazing in performance… until they discovered the
dynamic generation of machine code… and now they do the same thing!!!

But, I have to admit, when a programmer starts asking questions like this,
it is probably at worst something malicious, at best something “cute”, and
more than likely, something not at all on the scale of a driver like OpenGL.

It is probably “how can I overflow the buffer of a driver and cause it to
jump to the code my driver dynamically generated, so I can take over the
computer.”

Bart.

Gary G. Little wrote in message news:xxxxx@ntdev…
>
>
>
> Alberto,
>
> Sorry dude, but I have been around the computer stack a few times … and
> this practice was never “time-honored”. It was always considered a “last
> resort” “ain’t no other way” “error prone piece of crap”. Which it
genuinely
> is. The only engineers I have ever seen that considered it “time-honored”
> were the ones that had no life outside a keyboard and thought it a way to
> ensure their paycheck because no one else was smart enough to figure how
> they did this “magic”. Have I used this programming gimmick? Having
started
> in '74, of course I have, until computers and memory improved and I found
a
> better way. It is a classic “hack” … invoking the same religious fervor
as
> “goto” or not “goto”. The only place I would expect to see such code is
that
> brief interval when all of memory is being tested aftera power on. Using
it
> in a driver/application interface is an attempt to side step proper
> implementation of a device driver, because the company is to cheap to do
it
> right, or the engineer is still in his “cute programming phase”.
>
> Personally, I would invoke Greg Dyess’s injunction: “If this is a
> commercially produced driver, please let me know the product name so I can
> avoid wasting time with it.”
>
> > falls down the stairs.>
> –
> Gary G. Little
> xxxxx@broadstor.com
> xxxxx@inland.net
>
> wrote in message news:xxxxx@ntdev…
> >
> > Hi, Bounce,
> >
> > Generating code on the fly is a time-honored technique. Before
> > graphics chips had all 256 rops in hardware, for example, the
> > Microsoft DDK sample for the IBM 8514 generated code to do a rop-
> > bitblt on the fly, on the stack, then wrapped it in a segment, turned
> > on the execute bit, and did a far call to it. This generated code that
> > was by far faster than any kind of static code one could generate,
> > unless of course we stopped to code all 256 rops by hand.
> >
> > You have to learn how to use your segments, and how to set one
> > up ! I’m not sure the OS lets you do that kind of thing today, so you
> > may be on your own: read the Intel architecture book and learn how
> > to set up a new entry in your LDT. Generate your code, set up your
> > LDT entry, do a far call, wipe out your LDT entry, and collapse the
> > buffer. The worse that can happen is - and here’s the heretic
> > speaking again - is you having to tuck away the current LDT, set
> > up your own LDT and your own segment descriptor by hand,
> > instate your own LDT, far call your code, then reinstate the old
> > LDT. That can be done pretty fast too, if you take the appropriate
> > care, but it’s precise code, for grown ups to generate and maintain.
> >
> > Are you sure you want to do that ?
> >
> >
> > Alberto.
> >
> > ==========================
> >
> > On 3 May 2002, at 14:08, Johnny wrote:
> >
> > > First: I can’t see any reason, why you want to make the same code
> available
> > > to Ring3 and Ring0!!! It does somehow sound like Spaghetti-design.
> > >
> > > Second: In the Segment Descriptor, Type fields must be set to CODE and
> not
> > > DATA (with other words PAGES must have executable protection). In PDEs
> and
> > > PTEs if the Supervisor flag is set, the pages can be only accessed in
> Ring0.
> > > (If you have an MDL or Section and maps it into a Process Address
space,
> the
> > > problem with Supervisor is solved; it also solves the problem with DPL
> field
> > > of Segment Descriptor)
> > >
> > > Third: Your code must be self-relative. You can’t use direct addresses
> to
> > > acccess data (because the same code is going to run in Ring3 and
kernel
> > > address space is not accessible from Ring3==>GP#).
> > >
> > > Fourth: Don’t use any privilleged instructions in your code
> > >
> > > Last: I am really interested to know (If you can say) why the same
code
> > > should run in Ring0 and Ring3)
> > >
> > >
> > > Johnny
> > >
> > >
> > > -----Original Message-----
> > > From: xxxxx@lists.osr.com
> > > [mailto:xxxxx@lists.osr.com]On Behalf Of TheDonx
> > > Sent: Freitag, 3. Mai 2002 06:24
> > > To: NT Developers Interest List
> > > Subject: [ntdev] Execution of Dynamically Generated code.
> > >
> > >
> > > Hello All,
> > > My driver generates some code at run time ,I want to execute it from
> > > driver and application too.
> > > I have allocated page for it which is accessible from user and kernel.
> > > >From user app. how can I execute that page ?
> > >
> > > Thanx…
> > >
> > > —
> > > You are currently subscribed to ntdev as: xxxxx@yahoo.de
> > > To unsubscribe send a blank email to %%email.unsub%%
> > >
> > >
> > >
> > > _________________________________________________________
> > >
> > > Do You Yahoo!?
> > >
> > > Get your free @yahoo.com address at http://mail.yahoo.com
> > >
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntdev as: xxxxx@ieee.org
> > > To unsubscribe send a blank email to %%email.unsub%%
> > >
> >
> >
> >
> >
>
>
>
>

Excellent post Bart.

On-the-fly generation of code is not for the faint-of-heart, but as you illustrate there are definite requirements for it’s use. I remember “back in the day” when trying to do something in 6502 when there literally was no opcode that did what I wanted to do, so I had to modify a single byte of the instruction during run-time. It was of course well documented in the assembly what was going on, and it was the neatest solution to that particular problem. One really nice feature of the IBM 370 assembler is the “EX” opcode which explicitly modifies(and executes) a single target instruction. It’s a very powerful instruction, and used by compilers to generate efficient code.
My personal opinion is that any one who ever says “you should never use this or that” referring to a programming technique is close-minded and obstinate and doing themselves an injustice by not considering all options and tools available to perform a particular task.

Regards,

Paul Bunn, UltraBac Software, 425-644-6000
Microsoft MVP - Windows NT/2000/XP
http://www.ultrabac.com

-----Original Message-----
From: Bart Crane [mailto:xxxxx@iready.com]
Sent: Thursday, May 09, 2002 11:16 AM
To: NT Developers Interest List
Subject: [ntdev] Re: Execution of Dynamically Generated code.

OpenGL generates machine code dynamically and executes it.

“Last resort”? In the case of OpenGL, the “last resort” is to NOT
dynamically generate machine code.

“Error prone”? Not at all. Mapping the logical operations to machine code
is very straightforward. Sophisticated in the design and programming, yes.
Error-prone? Only while the code generator was being developed.

“Piece of crap”? OpenGL is a very, very impressive piece of work!! I am
honored to have spent time in the actual OpenGL source base. The dynamic
generation of machine code is key to its performance.

“Aint’ no other way”? OpenGL, when compiled for platforms that the machine
code generator does not support, uses pre-compiled C functions, but it is
much slower on those platforms.

From what I heard, the DirectX programmers at Microsoft could not figure out
how OpenGL was so amazing in performance… until they discovered the
dynamic generation of machine code… and now they do the same thing!!!

But, I have to admit, when a programmer starts asking questions like this,
it is probably at worst something malicious, at best something “cute”, and
more than likely, something not at all on the scale of a driver like OpenGL.

It is probably “how can I overflow the buffer of a driver and cause it to
jump to the code my driver dynamically generated, so I can take over the
computer.”

Bart.

Hello Paul,

Re: 6502 - do you mean that assembler had no mnemonic for the opcode you
wanted, and you manually set whatever bits in a “normal” instruction you
needed to get the desired effect? That’s cool!! I remember we needed to
insert data-bytes into the code stream for a similar reason, the assember
could not generate the opcode we wanted.

Did the information the original poster wanted ever surface? I was curious
as to what kind of code was being dynamically generated. We all have done
things like modify function pointers, which is a simple way of changing the
codepath at runtime, or have initialization code nop-out the jmp to
itself… self-modifying code, but not quite dynamically-generated code.

I recall one occasion where I wrote code that dynamically generated code and
executed it, but it is kind of silly…

I would overwrite a function with randomly (but dynamically!!) generated
register incs and decs and pushes and pops, a KB or so of rather
dense-looking asm code, whose only purpose was to make the code look really
hard… It was particularly easy because they were all 1-byte instructions,
and the generator just had to make sure there were never more pops than
pushes.

Every time the program ran it would generate a different set of this code,
the goal being to cause guys stepping through the program to get confused
and give up!! I can’t even remember what it was that I was going through so
much trouble to obfuscate!! It probably did not matter, it was just fun to
code!!

Oh, on the x86 these 1-byte instruction opcodes are also capital letters, so
it would look like the generator was creating text into the data segment,
but really silly segment arithmetic was pointing into the code segment.
And, since we were programming in assembly language, we could find exactly
the size/placement of functions, do math on the return-value on the stack…

Now I am remembering all sorts of these things… ah, the Good Ol’ Days of
DOS. I am going to have to think about this “Execution of Dynamically
Generated Code” a little more, maybe turn programming back into the real fun
it was!!!

Bart.

Paul Bunn wrote in message news:xxxxx@ntdev…
>
> Excellent post Bart.
>
> On-the-fly generation of code is not for the faint-of-heart, but as you
illustrate there are definite requirements for it’s use. I remember “back
in the day” when trying to do something in 6502 when there literally was no
opcode that did what I wanted to do, so I had to modify a single byte of the
instruction during run-time. It was of course well documented in the
assembly what was going on, and it was the neatest solution to that
particular problem. One really nice feature of the IBM 370 assembler is the
“EX” opcode which explicitly modifies(and executes) a single target
instruction. It’s a very powerful instruction, and used by compilers to
generate efficient code.
> My personal opinion is that any one who ever says “you should never use
this or that” referring to a programming technique is close-minded and
obstinate and doing themselves an injustice by not considering all options
and tools available to perform a particular task.
>
> Regards,
>
> Paul Bunn, UltraBac Software, 425-644-6000
> Microsoft MVP - Windows NT/2000/XP
> http://www.ultrabac.com
>
>
> -----Original Message-----
> From: Bart Crane [mailto:xxxxx@iready.com]
> Sent: Thursday, May 09, 2002 11:16 AM
> To: NT Developers Interest List
> Subject: [ntdev] Re: Execution of Dynamically Generated code.
>
>
> OpenGL generates machine code dynamically and executes it.
>
> “Last resort”? In the case of OpenGL, the “last resort” is to NOT
> dynamically generate machine code.
>
> “Error prone”? Not at all. Mapping the logical operations to machine
code
> is very straightforward. Sophisticated in the design and programming,
yes.
> Error-prone? Only while the code generator was being developed.
>
> “Piece of crap”? OpenGL is a very, very impressive piece of work!! I am
> honored to have spent time in the actual OpenGL source base. The dynamic
> generation of machine code is key to its performance.
>
> “Aint’ no other way”? OpenGL, when compiled for platforms that the
machine
> code generator does not support, uses pre-compiled C functions, but it is
> much slower on those platforms.
>
> From what I heard, the DirectX programmers at Microsoft could not figure
out
> how OpenGL was so amazing in performance… until they discovered the
> dynamic generation of machine code… and now they do the same thing!!!
>
> But, I have to admit, when a programmer starts asking questions like this,
> it is probably at worst something malicious, at best something “cute”, and
> more than likely, something not at all on the scale of a driver like
OpenGL.
>
> It is probably “how can I overflow the buffer of a driver and cause it to
> jump to the code my driver dynamically generated, so I can take over the
> computer.”
>
> Bart.
>
>

Dang, with all the controversy I have caused I don’t know if I should pop up
in this thread again …

Jan and Bart, you have given excellent arguments for the need, and the
abuse, of such a coding technique.

Debuggers use the technique. Note that the engine for KDB and WinDbg
dynamically change an op-code to INT 3. By definition that is self-modifying
code – and I use the HELL out of WinDbg. In the 70’s, working on a
MicroData 1600 we had a ZAP program that loaded the delivered, target
program from disk and allowed us to edit and change the machine code to
insert patches. In fact, we used the front panel of the 1600 to halt the
program, set the IP address, enter the patch through the front panel, and
then run the program and OS with the changes. IBM delivered PATCH files for
a long time that did much the same thing. I do recall one friend taking the
machine code card deck of an IBM 360 program, locating the proper card that
had the instructions he was looking for, duping and keypunching the card to
make the proper changes, putting the card back in the deck and then loading
and running the program. It worked.

I have however, to many times in 30 years, dealt with the “geniuses” that
used such techniques for malicious mischief and for job security. So I do
hereby publicly re-cant – Self modifying code does indeed have its place in
a toolkit. :slight_smile:


Gary G. Little
xxxxx@broadstor.com
xxxxx@inland.net

“Bart Crane” wrote in message news:xxxxx@ntdev…
>
> OpenGL generates machine code dynamically and executes it.
>
> “Last resort”? In the case of OpenGL, the “last resort” is to NOT
> dynamically generate machine code.
>
> “Error prone”? Not at all. Mapping the logical operations to machine
code
> is very straightforward. Sophisticated in the design and programming,
yes.
> Error-prone? Only while the code generator was being developed.
>
> “Piece of crap”? OpenGL is a very, very impressive piece of work!! I am
> honored to have spent time in the actual OpenGL source base. The dynamic
> generation of machine code is key to its performance.
>
> “Aint’ no other way”? OpenGL, when compiled for platforms that the
machine
> code generator does not support, uses pre-compiled C functions, but it is
> much slower on those platforms.
>
> From what I heard, the DirectX programmers at Microsoft could not figure
out
> how OpenGL was so amazing in performance… until they discovered the
> dynamic generation of machine code… and now they do the same thing!!!
>
> But, I have to admit, when a programmer starts asking questions like this,
> it is probably at worst something malicious, at best something “cute”, and
> more than likely, something not at all on the scale of a driver like
OpenGL.
>
> It is probably “how can I overflow the buffer of a driver and cause it to
> jump to the code my driver dynamically generated, so I can take over the
> computer.”
>
> Bart.
>
> Gary G. Little wrote in message
news:xxxxx@ntdev…
> >
> >
> >
> > Alberto,
> >
> > Sorry dude, but I have been around the computer stack a few times …
and
> > this practice was never “time-honored”. It was always considered a “last
> > resort” “ain’t no other way” “error prone piece of crap”. Which it
> genuinely
> > is. The only engineers I have ever seen that considered it
“time-honored”
> > were the ones that had no life outside a keyboard and thought it a way
to
> > ensure their paycheck because no one else was smart enough to figure how
> > they did this “magic”. Have I used this programming gimmick? Having
> started
> > in '74, of course I have, until computers and memory improved and I
found
> a
> > better way. It is a classic “hack” … invoking the same religious
fervor
> as
> > “goto” or not “goto”. The only place I would expect to see such code is
> that
> > brief interval when all of memory is being tested aftera power on. Using
> it
> > in a driver/application interface is an attempt to side step proper
> > implementation of a device driver, because the company is to cheap to do
> it
> > right, or the engineer is still in his “cute programming phase”.
> >
> > Personally, I would invoke Greg Dyess’s injunction: “If this is a
> > commercially produced driver, please let me know the product name so I
can
> > avoid wasting time with it.”
> >
> > and
> > falls down the stairs.>
> > –
> > Gary G. Little
> > xxxxx@broadstor.com
> > xxxxx@inland.net
> >
> > wrote in message news:xxxxx@ntdev…
> > >
> > > Hi, Bounce,
> > >
> > > Generating code on the fly is a time-honored technique. Before
> > > graphics chips had all 256 rops in hardware, for example, the
> > > Microsoft DDK sample for the IBM 8514 generated code to do a rop-
> > > bitblt on the fly, on the stack, then wrapped it in a segment, turned
> > > on the execute bit, and did a far call to it. This generated code that
> > > was by far faster than any kind of static code one could generate,
> > > unless of course we stopped to code all 256 rops by hand.
> > >
> > > You have to learn how to use your segments, and how to set one
> > > up ! I’m not sure the OS lets you do that kind of thing today, so you
> > > may be on your own: read the Intel architecture book and learn how
> > > to set up a new entry in your LDT. Generate your code, set up your
> > > LDT entry, do a far call, wipe out your LDT entry, and collapse the
> > > buffer. The worse that can happen is - and here’s the heretic
> > > speaking again - is you having to tuck away the current LDT, set
> > > up your own LDT and your own segment descriptor by hand,
> > > instate your own LDT, far call your code, then reinstate the old
> > > LDT. That can be done pretty fast too, if you take the appropriate
> > > care, but it’s precise code, for grown ups to generate and maintain.
> > >
> > > Are you sure you want to do that ?
> > >
> > >
> > > Alberto.
> > >
> > > ==========================
> > >
> > > On 3 May 2002, at 14:08, Johnny wrote:
> > >
> > > > First: I can’t see any reason, why you want to make the same code
> > available
> > > > to Ring3 and Ring0!!! It does somehow sound like Spaghetti-design.
> > > >
> > > > Second: In the Segment Descriptor, Type fields must be set to CODE
and
> > not
> > > > DATA (with other words PAGES must have executable protection). In
PDEs
> > and
> > > > PTEs if the Supervisor flag is set, the pages can be only accessed
in
> > Ring0.
> > > > (If you have an MDL or Section and maps it into a Process Address
> space,
> > the
> > > > problem with Supervisor is solved; it also solves the problem with
DPL
> > field
> > > > of Segment Descriptor)
> > > >
> > > > Third: Your code must be self-relative. You can’t use direct
addresses
> > to
> > > > acccess data (because the same code is going to run in Ring3 and
> kernel
> > > > address space is not accessible from Ring3==>GP#).
> > > >
> > > > Fourth: Don’t use any privilleged instructions in your code
> > > >
> > > > Last: I am really interested to know (If you can say) why the same
> code
> > > > should run in Ring0 and Ring3)
> > > >
> > > >
> > > > Johnny
> > > >
> > > >
> > > > -----Original Message-----
> > > > From: xxxxx@lists.osr.com
> > > > [mailto:xxxxx@lists.osr.com]On Behalf Of TheDonx
> > > > Sent: Freitag, 3. Mai 2002 06:24
> > > > To: NT Developers Interest List
> > > > Subject: [ntdev] Execution of Dynamically Generated code.
> > > >
> > > >
> > > > Hello All,
> > > > My driver generates some code at run time ,I want to execute it from
> > > > driver and application too.
> > > > I have allocated page for it which is accessible from user and
kernel.
> > > > >From user app. how can I execute that page ?
> > > >
> > > > Thanx…
> > > >
> > > > —
> > > > You are currently subscribed to ntdev as: xxxxx@yahoo.de
> > > > To unsubscribe send a blank email to %%email.unsub%%
> > > >
> > > >
> > > >
> > > > _________________________________________________________
> > > >
> > > > Do You Yahoo!?
> > > >
> > > > Get your free @yahoo.com address at http://mail.yahoo.com
> > > >
> > > >
> > > >
> > > >
> > > > —
> > > > You are currently subscribed to ntdev as: xxxxx@ieee.org
> > > > To unsubscribe send a blank email to %%email.unsub%%
> > > >
> > >
> > >
> > >
> > >
> >
> >
> >
> >
>
>
>
>

On Wed, 15 May 2002, Gary G. Little wrote:

Debuggers use the technique. Note that the engine for KDB and WinDbg
dynamically change an op-code to INT 3. By definition that is self-modifying
code
Only when you’re debugging the debugger.

If you’re not, they’re not /self/ modifying, just patching running code.


Peter xxxxx@inkvine.fluff.org
http://www.inkvine.fluff.org/~peter/

logic kicks ass:
(1) Horses have an even number of legs.
(2) They have two legs in back and fore legs in front.
(3) This makes a total of six legs, which certainly is an odd number of
legs for a horse.
(4) But the only number that is both odd and even is infinity.
(5) Therefore, horses must have an infinite number of legs.