Za dodatnu sigurnost treba postaviti "osiguranim" procesima stack limit na 8 MB (ili koliko vec treba - tada se treba prilagoditi i granica code segmenta). Jer inace program moze zauzeti dovoljno stacka i tako ga prosiriti u code segment.
Evo primjer koda za linux:
Code:
#include <stdio.h>
#include <string.h>
#include <asm/ldt.h>
#include <linux/unistd.h>
void test()
{
int ret = 0xC3C3C3C3; /* C3 je kod za RET instrukciju */
void (*fn)(void) = &ret;
printf("trying stack call...");
fflush(stdout);
fn();
printf("done!!\n");
}
int main()
{
struct modify_ldt_ldt_s ldt;
printf("Before modify_ldt: "); test();
ldt.entry_number = 1;
ldt.base_addr = 0;
ldt.limit = 0xBF800; /* 3GB - 8MB */
ldt.seg_32bit = 1;
ldt.contents = 2; /* execute/read */
ldt.read_exec_only = 0; /* allow read in exec segments */
ldt.limit_in_pages = 1;
ldt.seg_not_present = 0;
ldt.useable = 0;
if(modify_ldt(1, &ldt, sizeof(ldt)) < 0) {
perror("modify_ldt");
exit(1);
}
/* Nema instrukcija tipa movw %ax,%cs. Mora se izvesti FAR JUMP. */
printf("After modify_ldt: ");
asm("ljmp $0x0F, $0f; 0: nop");
test();
return 0;
}
#include <stdio.h>
#include <string.h>
#include <asm/ldt.h>
#include <linux/unistd.h>
void test()
{
int ret = 0xC3C3C3C3; /* C3 je kod za RET instrukciju */
void (*fn)(void) = &ret;
printf("trying stack call...");
fflush(stdout);
fn();
printf("done!!\n");
}
int main()
{
struct modify_ldt_ldt_s ldt;
printf("Before modify_ldt: "); test();
ldt.entry_number = 1;
ldt.base_addr = 0;
ldt.limit = 0xBF800; /* 3GB - 8MB */
ldt.seg_32bit = 1;
ldt.contents = 2; /* execute/read */
ldt.read_exec_only = 0; /* allow read in exec segments */
ldt.limit_in_pages = 1;
ldt.seg_not_present = 0;
ldt.useable = 0;
if(modify_ldt(1, &ldt, sizeof(ldt)) < 0) {
perror("modify_ldt");
exit(1);
}
/* Nema instrukcija tipa movw %ax,%cs. Mora se izvesti FAR JUMP. */
printf("After modify_ldt: ");
asm("ljmp $0x0F, $0f; 0: nop");
test();
return 0;
}