Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

add -gx to add stack smash code #1542

Merged
merged 1 commit into from

5 participants

@WalterBright

With -gx switch, adds code to smash the local variables upon function exit. Useful for flushing out heisenbugs.

A partial implementation of bug http://d.puremagic.com/issues/show_bug.cgi?id=9242

@alexrp

Maybe a different name? The term "stack smashing" is usually used in the context of the stack smashing protector that GCC and LLVM support: http://llvm.org/docs/LangRef.html#llvm-stackprotector-intrinsic (see also the ssp, sspreq, and sspstrong attributes in that document)

@WalterBright

I don't see the word "smash" in the linked page.

@yebblies
Collaborator

Why do you have this disabled for win64?

@yebblies
Collaborator

Sorry, I'm tried. What I meant to ask was - is this really equivalent to all of the other epilogs? And if so, could they be merged together instead of having a universal stack smash version and several target dependent versions?

@WalterBright

The other ones are optimal for different purposes, as the if statements set out. The win64 is different because the win64 api says it should be that way, see the supplied url.

@klickverbot
Collaborator

I know I've used smashStack as function name in some code snippets I posted on the forums in the past, but when reading about »stack smashing« in connection with compilers, I think about the exploitation technique (as in the seminal »Smashing the Stack for Fun and Profit« paper) and related countermeasures, not a debugging helper.

So maybe »overwrite stack with garbage when returning from a function« or something along the lines would be a better description for a flag? A reference to »stack smashing code« would probably need further explanation in the (non-existent?) docs, unless you are building an exploit kit. ;)

@leandro-lucarella-sociomantic
@WalterBright

stomping sounds good

@WalterBright WalterBright merged commit b8d5ce9 into D-Programming-Language:master
@WalterBright WalterBright deleted the unknown repository branch
src/backend/backconfig.c
@@ -47,7 +47,8 @@ void out_config_init(
int symdebug, // add symbolic debug information
// 1: D
// 2: fake it with C symbolic debug info
- bool alwaysframe // always create standard function frame
+ bool alwaysframe, // always create standard function frame
+ bool stacksmash // add stack smashing code

Haha, it looks like you're using smashing in the code after all :P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@MartinNowak MartinNowak referenced this pull request
Merged

rename smash -> stomp #1552

@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
@ghost Unknown referenced this pull request from a commit
Commit has since been removed from the repository and is no longer available.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 24, 2013
  1. @WalterBright
This page is out of date. Refresh to see the latest.
View
5 src/backend/backconfig.c
@@ -47,7 +47,8 @@ void out_config_init(
int symdebug, // add symbolic debug information
// 1: D
// 2: fake it with C symbolic debug info
- bool alwaysframe // always create standard function frame
+ bool alwaysframe, // always create standard function frame
+ bool stacksmash // add stack smashing code

Haha, it looks like you're using smashing in the code after all :P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
)
{
#if MARS
@@ -193,6 +194,8 @@ void out_config_init(
if (alwaysframe)
config.flags |= CFGalwaysframe;
+ if (stacksmash)
+ config.flags2 |= CFG2smash;
ph_init();
block_init();
View
3  src/backend/cdef.h
@@ -766,9 +766,10 @@ struct Config
#define CFG2noerrmax 0x4000 // no error count maximum
#define CFG2expand 0x8000 // expanded output to list file
#define CFG2seh 0x10000 // use Win32 SEH to support any exception handling
+#define CFG2smash 0x20000 // enable stack smashing code
#define CFGX2 (CFG2warniserr | CFG2phuse | CFG2phgen | CFG2phauto | \
CFG2once | CFG2hdrdebug | CFG2noobj | CFG2noerrmax | \
- CFG2expand | CFG2nodeflib)
+ CFG2expand | CFG2nodeflib | CFG2smash)
unsigned flags3;
#define CFG3ju 1 // char == unsigned char
#define CFG3eh 4 // generate exception handling stuff
View
32 src/backend/cod3.c
@@ -3470,7 +3470,37 @@ void epilog(block *b)
assert(hasframe);
if (xlocalsize | usedalloca)
{
- if (config.exe == EX_WIN64)
+ if (config.flags2 & CFG2smash)
+ { /* MOV ECX,0xBEAF
+ * L1:
+ * MOV [ESP],ECX
+ * ADD ESP,4
+ * CMP EBP,ESP
+ * JNE L1
+ * POP EBP
+ */
+ /* Value should be:
+ * 1. != 0 (code checks for null pointers)
+ * 2. be odd (to mess up alignment)
+ * 3. fall in first 64K (likely marked as inaccessible)
+ * 4. be a value that stands out in the debugger
+ */
+ assert(I32 || I64);
+ targ_size_t value = 0x0000BEAF;
+ reg_t reg = CX;
+ mfuncreg &= ~mask[reg];
+ unsigned grex = I64 ? REX_W << 16 : 0;
+ c = genc2(c,0xC7,grex | modregrmx(3,0,reg),value); // MOV reg,value
+ code *c1 = gen2sib(CNIL,0x89,grex | modregrm(0,reg,4),modregrm(0,4,SP)); // MOV [ESP],reg
+ genc2(c1,0x81,grex | modregrm(3,0,SP),REGSIZE); // ADD ESP,REGSIZE
+ genregs(c1,0x39,SP,BP); // CMP EBP,ESP
+ if (I64)
+ code_orrex(c1,REX_W);
+ genjmp(c1,JNE,FLcode,(block *)c1); // JNE L1
+ gen1(c1,0x58 + BP); // POP BP
+ c = cat(c,c1);
+ }
+ else if (config.exe == EX_WIN64)
{ // See http://msdn.microsoft.com/en-us/library/tawsa7cb(v=vs.80).aspx
// LEA RSP,0[RBP]
c = genc1(c,LEA,(REX_W<<16)|modregrm(2,SP,BPRM),FLconst,0);
View
3  src/mars.c
@@ -336,6 +336,7 @@ Usage:\n\
" -g add symbolic debug info\n\
-gc add symbolic debug info, pretend to be C\n\
-gs always emit stack frame\n\
+ -gx add stack stomp code\n\
-H generate 'header' file\n\
-Hddirectory write 'header' file to directory\n\
-Hffilename write 'header' file to filename\n\
@@ -566,6 +567,8 @@ int tryMain(size_t argc, char *argv[])
global.params.symdebug = 2;
else if (strcmp(p + 1, "gs") == 0)
global.params.alwaysframe = 1;
+ else if (strcmp(p + 1, "gx") == 0)
+ global.params.stackstomp = true;
else if (strcmp(p + 1, "gt") == 0)
{ error(0, "use -profile instead of -gt");
global.params.trace = 1;
View
1  src/mars.h
@@ -168,6 +168,7 @@ struct Param
// 1: array bounds checks for safe functions only
// 2: array bounds checks for all functions
char noboundscheck; // no array bounds checking at all
+ bool stackstomp; // add stack stomping code
char useSwitchError; // check for switches without a default
char useUnitTests; // generate unittest code
char useInline; // inline expand functions
View
6 src/msc.c
@@ -46,7 +46,8 @@ void out_config_init(
int symdebug, // add symbolic debug information
// 1: D
// 2: fake it with C symbolic debug info
- bool alwaysframe // always create standard function frame
+ bool alwaysframe, // always create standard function frame
+ bool stackstomp // add stack stomping code
);
void out_config_debug(
@@ -93,7 +94,8 @@ void backend_init()
params->verbose,
params->optimize,
params->symdebug,
- params->alwaysframe
+ params->alwaysframe,
+ params->stackstomp
);
#ifdef DEBUG
Something went wrong with that request. Please try again.