📄 main.c
字号:
r=pk->c_pos;
eraseSuspicious1(r);
}
return 1;
}
// *******************************************
// label handling functions
// *******************************************
int BadEnter(PBYTE p, int ref, int pos)
{
static BYTE mapByte[32]={
0x05,0x07,0x15,0x17,0x20,0x25,0x27,0x87,
0x35,0x37,0x40,0x45,0x47,0x55,0x60,0x85,
0x65,0x75,0xA5,0xA7,0xA0,0xB5,0xB7,0x00};
if(strchr(mapByte,*p)!=NULL) return 0;
fprintf(stderr,"%02X",*p);
//fprintf(stdout,"%02X:pos=%08X:ref=%08X:",*p,pos,ref);
fatalPosition=pos;
fatalReference=ref;
fatalError=998;
return 1;
}
//=================================================================================
// I need to describe the intended usage of _key_ and its fields.
// as you can see the _key_ structure consists of three fields
// _key_ ::= class, c_pos, c_ref
// class tells what kind of reference we are dealing with
// the table shows:
//---------------------------------------------------------------------------------
// class of reference | unconditional(jump or call) | conditional jump |
// --------------------------------------------------------------------------------
// Jmp Short Rel Disp | 1 | 2 |
// Jmp Near Rel Disp | 3 | 4 |
// Jmp Near Abs Indir | 5 | *** |
// Jmp Far Absolute | 7 | *** |
// Jmp Far Abs Indir | 9 | *** |
// Call Near Rel Disp | 11 | *** |
// Call Near Abs Indir | 13 | *** |
// Call Far Absolute | 15 | *** |
// Call Far Abs Indir | 17 | *** |
//---------------------------------------------------------------------------------
// Jmp indirect address holding place 133 |
// the reference which is pointed by above address 165 |
// the reference which is adjacent to above 165 166 |
// the possible reference by -- push dword 512 |
// the possible reference by -- push [reg or mem] 513 |
// the possible reference by -- mov [reg or mem], dword 1024 |
// the definitive reference by export function block 2048 |
//---------------------------------------------------------------------------------
//=================================================================================
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// this one tell what is lpMap and its intended usage...
//-------------------------------------------------------------------//
// //
// I can use lpMap (code check buffer?) //
//-------------------------------------------------------------------//
// 0x00: unprocessed //
// 0x01: starting position of instruction (masked) //
// 0x02: gray mark(suspicious code) (masked) //
// 0x04: processed instructions (masked) //
// 0x08: data(address, byte, CC block) (no masking) //
// 0x0C: cc block " //
// 0x0E: address " //
// 0x0F: byte " //
// 0x10: label generated here (masked) //
// 0x20: start point set (masked) //
// 0x40: entry or not (masked) //
// 0x80: anchor set (masked) //
//-------------------------------------------------------------------//
// this function tries to record all the possible entries and labels
// and data references we can find and decipher.
int EnterLabel(int class, int ref, int pos)
{
int r, rr, d;
_key_ k;
PKEY pk;
int *q;
PBYTE p;
//{fprintf(stderr,"EnterLabel::class=%5dX,ref=%08X\n",class,ref);getch();}
if (ref<imagebaseRVA) return 0;
if (!AddressCheck(pos)) return 0;
if (ref<imagebaseRVA+CodeSize)
{
switch(class)
{
case 1: case 2: case 3: case 4: case 7: case 11: case 15: case 165:
k.class = class;
k.c_pos = pos;
k.c_ref = ref;
MyBtreeInsert(&k);
k.class = -class;
k.c_pos = ref;
k.c_ref = pos;
p = toMap(ref);
MyBtreeInsert(&k); // we can use this .. for erase uncertain case.
if (BadEnter(p,ref,pos)) break;
if (!(*p&0x20))
{if (minEntry>ref) minEntry=ref; newEntry++; *p |= 0x20;}
p = toMap(pos);
*p |= 0x10;
break;
case 166:
// mark that address data
p = toMap(pos); addedAddress++;
*p = 0x0E; *(p+1) = 0x0E; *(p+2) = 0x0E; *(p+3) = 0x0E;
k.class = class;
k.c_pos = pos;
k.c_ref = ref;
MyBtreeInsert(&k);
k.class = -class;
k.c_pos = ref;
k.c_ref = pos; // we can use this .. for erase uncertain case.
MyBtreeInsert(&k);
p=toMap(ref);
if (BadEnter(p,ref,pos)) break;
if (!(*p&0x20))
{if (minEntry>ref) minEntry=ref; newEntry++; *p |= 0x20;}
break;
case 512: case 513: case 1024:
k.class = class;
k.c_pos = pos;
k.c_ref = ref;
MyBtreeInsert(&k);
k.class = -class;
k.c_pos = ref;
k.c_ref = pos; // we can use this .. for erase uncertain case.
MyBtreeInsert(&k);
break;
//-------------------------------------------------------------------//
// now it is indirect address reference and we need to take some //
// serious actions, namely if it is preventable than it is OK //
// but if bad deed is already done we need to UNDO it. //
// this requires couple of things. //
// first we need to store indirect references in some convenient way //
// and every time we need to check whether we touch it or not. //
// second we need to store all the anchors and start positions //
// so we can easily determine how much we need to UNDO. //
// october 24, 1997 late night-- sang cho //
//-------------------------------------------------------------------//
case 5: case 9: case 13: case 17: case 133:
// mark that address data
if (ref<pos+4) { eraseUncertain(ref); break; }
p = toMap(ref); addedAddress++;
*p = 0x0E; *(p+1) = 0x0E; *(p+2) = 0x0E; *(p+3) = 0x0E;
k.class = class;
k.c_pos = pos;
k.c_ref = ref;
MyBtreeInsert(&k);
k.class = -class;
k.c_pos = ref;
k.c_ref = pos;
MyBtreeInsert(&k); // we can use this .. for erase uncertain case.
p = toMap(pos);
*p |= 0x10;
// I am forming chain of label references.
// also new class is defined here.
r = Get32Address(ref);
if (r>0)
{
k.class = class + 32;
k.c_pos = ref;
k.c_ref = r;
if (AddressCheck(r))
{
p = toMap(r);
MyBtreeInsert(&k);
if (BadEnter(p,r,pos)) break;
if (!(*p&0x20))
{if (minEntry>r) minEntry=r; newEntry++; *p |= 0x20;}
}
}
break;
// I need to UNDO that bad deed, I once did.
// but this one is in the middle of printing really something untouchable,
// so what should I do, can I preempt it and proceed what I have to do?
// well... if I am more careful I think I can do that.
// OK this is fixed now, I can progress as I wished. october 25, 1997
// the following code is move to above position....^^^^^.....
//if (ref<pos+4) { eraseUncertain(ref); break; }
default:
}
}
//
// if reference is out of code range what can I do?
// I have to think about it a while, meantime I'll just
// do the thing I can do.
//
else
{
switch(class)
{
case 3: case 4:
fatalError=950;
break;
case 7: case 11: case 15: case 165:
r = Get32Address(ref);
if (r>0)
{
k.class = class;
k.c_pos = pos;
k.c_ref = r;
MyBtreeInsert(&k);
k.class = -class;
k.c_pos = r;
k.c_ref = pos;
MyBtreeInsert(&k); // we can use this .. for erase uncertain case.
}
break;
case 166:
// mark that address data
p = toMap(pos); addedAddress++;
*p = 0x0E; *(p+1) = 0x0E; *(p+2) = 0x0E; *(p+3) = 0x0E;
k.class = class;
k.c_pos = pos;
k.c_ref = ref;
MyBtreeInsert(&k);
k.class = -class;
k.c_pos = ref;
k.c_ref = pos; // we can use this .. for erase uncertain case.
MyBtreeInsert(&k);
break;
case 512: case 513: case 1024:
{
k.class = class;
k.c_pos = pos;
k.c_ref = ref;
MyBtreeInsert(&k);
k.class = -class;
k.c_pos = ref;
k.c_ref = pos;
MyBtreeInsert(&k); // we can use this .. for erase uncertain case.
}
break;
case 5: case 9: case 13: case 17: case 133:
// mark that address data
r = Get32Address(ref);
if (r>0)
{
k.class = class;
k.c_pos = pos;
k.c_ref = r;
MyBtreeInsert(&k);
k.class = -class;
k.c_pos = r;
k.c_ref = pos;
MyBtreeInsert(&k); // we can use this .. for erase uncertain case.
// I am forming chain of label references.
// also new class is defined here.
rr = Get32Address(r);
if (rr>0)
{
k.class = class + 32;
k.c_pos = r;
k.c_ref = rr;
MyBtreeInsert(&k);
}
}
default:
}
}
}
// this is inverse of EnterLabel, but... who knows!
int DeleteLabels(int ref)
{
int r, rr;
_key_ k, k1, k2, k3, k4;
PKEY pk;
PBYTE p;
//{fprintf(stderr, "(%08X)DeleteLabels:\n",ref);getch();}
// this is very tricky.. i need to be extremely careful. oct.29,1997sangcho
k.c_ref=ref; k.c_pos=0; k.class=0;
pk = searchBtree1(&k);
if(pk==NULL) return 1;
k1=*pk;
k.class=-k1.class; k.c_pos=k1.c_ref; k.c_ref=k1.c_pos;
pk = searchBtree1(&k);
if(pk==NULL) return 1;
k2=*pk;
if(k2.class==133 || k2.class==5 || k2.class==9 || k2.class==13 || k2.class==17)
{
r=Get32Address(k2.c_ref);
rr=Get32Address(r);
if (r>0)
{
k3.class = k2.class + 32;
k3.c_pos = k2.c_ref;
k3.c_ref = r;
// now we have to delete k3
if (MyBtreeDelete(&k3)==0)
{
p=toMap(k3.c_ref);
if ((*p)&0x20)
{
*p^=0x20; delEntry++;
}
}
}
}
else if(MyBtreeDelete(&k2)==0)
{
p=toMap(k2.c_ref);
if ((*p)&0x20)
{
*p^=0x20;
}
}
// we have to delete k1 and k2
MyBtreeDelete(&k1);
//fprintf(stdout,"deleted label==%5d::%08X<<%08X\n",k2.class,k2.c_ref,k2.c_pos);
return 1;
}
// **********************************************
// address checking or getactual address. etc...
// **********************************************
int isGoodAddress(int ref)
{
int d;
d=ref-cur_position;
if ((imagebaseRVA<ref)&&(ref<imagebaseRVA+CodeSize)
&&(-TOLERANCE<d && d<TOLERANCE))
return 1; else return 0;
}
int AddressCheck(int ref)
{
if (ref<imagebaseRVA) return 0;
if (ref<imagebaseRVA+CodeSize) return ref;
if (ref<imageBase+maxRVA+maxRVAsize) return ref;
return 0;
}
int Get32Address(int ref)
{
int r;
if (ref<imagebaseRVA) return 0;
if (ref<imagebaseRVA+CodeSize)
return AddressCheck(*(int *)((int)lpFile+ref-imagebaseRVA+CodeOffset));
r=(int)GetActualAddress(lpFile, ref-imageBase);
return (*(int *)(r));
}
int isThisSecure(int ref)
{
_key_ k;
PKEY pk;
BYTE b=*toFile(ref);
BYTE c=*toMap(ref);
int r, n;
if (b==0xC3) return 1;
if (!(c&0x10)) return 0;
if (b==0xE9||b==0xFF||b==0xEB)
{
k.class=0;k.c_ref=ref;k.c_pos=0;
pk=searchBtree1(&k);
r=pk->c_pos;
if(!AddressCheck(r))
{
k.c_ref=r;k.c_pos=0;k.class=0;
pk=searchBtree1(&k);
if(pk==NULL)return 0;
else return 1;
}
n=referCount(r);
if(n>1)return 1;
if(n>0&&(b==0xE9||b==0xFF))return 1;
if(n>0&&r<imagebaseRVA+CodeSize&&(*toMap(r)&0x60))return 1;
}
return 0;
}
int isNotGoodJump(int ref)
{
_key_ k;
PKEY pk;
BYTE b=*toFile(ref);
int r;
if (b==0xC3) return 0;
if (b==0xC2) return 0;
if (b==0xE9||b==0xFF)
{
k.class=0;k.c_ref=ref;k.c_pos=0;
pk=searchBtree1(&k);
r=pk->c_pos;
if(!AddressCheck(r))
{
k.c_ref=r;k.c_pos=0;k.class=0;
pk=searchBtree1(&k);
if(pk==NULL)return 1;
else return 0;
}
if(r<imagebaseRVA+CodeSize&&(*toMap(r)&0x20))return 0;
if(r>imagebaseRVA+CodeSize&&referCount(r)>0)return 0;
}
return 1;
}
PBYTE toMap(int ref)
{
if(ref<imagebaseRVA) return NULL;
if(ref>imagebaseRVA+CodeSize) return NULL;
return (PBYTE)(ref-imagebaseRVA+(int)lpMap);
}
PBYTE toFile(int ref)
{
if(ref<imagebaseRVA) return NULL;
if(ref>imagebaseRVA+fsize) return NULL;
if (ref<imagebaseRVA+CodeSize)
return (PBYTE)(ref-imagebaseRVA+(int)lpFile+CodeOffset);
return (PBYTE)GetActualAddress(lpFile,ref-imageBase);
}
int fromMap(PBYTE p)
{
return (int)p-(int)lpMap+imagebaseRVA;
}
int fromFile(PBYTE p)
{
return (int)p-(int)lpFile-CodeOffset+imagebaseRVA;
}
//
// I cannot actually compute m16:m32 far address value
// so I will only record m32 part of it, hope it actually works.
//
int Get16_32Address(int ref)
{
return Get32Address(ref);
}
// *************************************
// miscellaneous functions
// *************************************
int Myfinish()
{
free ((void *)piNameBuff);
free ((void *)peNameBuff);
free ((void *)lpFile);
free ((void *)lpMap);
Btree_deleteall(head, &btn);
Btree_deleteall(headx,&btnx);
exit(0);
}
int nullxx(const char *s,...)
{
return 1;
}
// =============================================================
// I am using two B-trees namely head and headx.
// the reason to do so is as follows:
//
// head tree contains reference and position pair plus class
//
// where reference:the position called, jumped, etc.
// position: where above reference is made.
// class: the kind of reference. (explained in EnterLabel)
//
// headx tree contains the reversed pair of above pair plus -class
// so i can trace which reference i am looking for.
// besides that i use headx for some other purposes, like
// keep count of reference: which is weighted for some reason i guess.
// the bigger the count is it is safe to keep this reference.
// when some volatile situation occurs i will consult this reference
// count. whenever new reference is made the count is updated.
// namely increased or decreased.
//
// for reference count i use c_pos for jump count and
// class for call count
// c_ref is highest bit set to 1....
//
// november 5,1997 --sangcho--
/* ******************************************************* */
/* BTREEI.C : */
/* Programmed By Lee jaekyu */
/* modified by sangcho--october 22,1997 */
/* modified by sangcho--november 5,1997 */
/* ******************************************************* */
int EQ(PKEY p, PKEY q)
{
if (p->class>0)
{
if ((p->c_ref==q->c_ref)&&(p->c_pos==q->c_pos)) return 1;
else return 0;
}
if (p->c_ref==q->c_ref) return 1;
return 0;
}
int GE(PKEY p, PKEY q)
{
if (p->class>0)
{
if (p->c_ref>q->c_ref) return 1;
else if ((p->c_ref==q->c_ref)&&(p->c_pos >= q->c_pos)) return 1;
return 0;
}
if (p->c_ref >= q->c_ref) return 1;
return 0;
}
int GT(PKEY p, PKEY q)
{
if (p->class>0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -