有用过IDA的强人吗 ,帮个忙看看

时间:2022-10-30 04:53:54
有用过IDA的强人吗 ,帮个忙看看
用IDA看了下某驱动的数据定义

为什么里面什么都没呢

还有 IDA里面找到了我想要的如何转到它运行的内存地址呢

比如我在里面找到 mov eax,eax 它运行在内核后怎么找到 mov eax,eax此处的地址?

机器码搜索 此驱动罕大相同的多不说还麻烦

初学 请不吝赐教

46 个解决方案

#1


对啊 我记得汇编里 ;后面的是注释
为什么呢 IDA没把数据显示出来?
有用过IDA的强人吗 ,帮个忙看看

#2


LZ的头像a

#3


只是分配一些空间用,其初始值没有意义。

#4


引用 3 楼 zhao4zhong1 的回复:
只是分配一些空间用,其初始值没有意义。

未初始化的变量
第二个问题是
IDA开始地址 10001
10010  mov eax,eax

枚举内核模块 找到目标驱动的Base +10

这样吗 昨晚临睡前想想 好像是这样 呵呵

#5


引用 2 楼 zhoutanliang 的回复:
LZ的头像a

头像怎么了

#6


炯炯有神!

#7


引用 6 楼 zhao4zhong1 的回复:
炯炯有神!

呵呵 

是吗

我的第二个问题啊


IDA显示的:

第一条语句的地址是 10001
mov eax,eax 地址是10010
驱动基址+(10010-10001) =mov eax,eax的地址

#8


有没有源代码?有的话加int 3 断点。

没有的话,使用文件偏移-->内存偏移 转换。

#9


引用 8 楼 mydo 的回复:
有没有源代码?有的话加int 3 断点。

没有的话,使用文件偏移-->内存偏移 转换。

当然不是我自己的驱动

"使用文件偏移-->内存偏移 转换"此句怎么解?

#10


哪位可以告诉我方法

使用文件偏移-->内存偏移


有用过IDA的强人吗 ,帮个忙看看
将图上的01001026转到内存地址怎么计算的?

#11


怎么沉了 自己UP下

#12


IDA的问题还是去看雪吧

#13


引用 12 楼 wodemuyecun 的回复:
IDA的问题还是去看雪吧

看雪全都潜水 没个回答... 

#14


这个可能是运行后才赋值

#15


你是不是走火入魔了,不要把有限的生命浪费在无限的加密解密死循环中!

#16


引用 15 楼 lactoferrin 的回复:
你是不是走火入魔了,不要把有限的生命浪费在无限的加密解密死循环中!

才没!
我想解决个DebugPort清零
我用IDA找到它清零的地方了 我想把它在内存NOP掉

#17


引用 15 楼 lactoferrin 的回复:
你是不是走火入魔了,不要把有限的生命浪费在无限的加密解密死循环中!


列宁同志可以教下我吗 在IDA里面的地址转到内存地址

对啊 都搞了这么久了 
速度搞定干别的去

#18


ida是静态分析,你这里看起来是运行后再分配的位置,只有运行后才能看得到

#19


如果我搞一个东西半天搞不出来我就不搞了

#20


引用 18 楼 lactoferrin 的回复:
ida是静态分析,你这里看起来是运行后再分配的位置,只有运行后才能看得到

难道要机器码搜索吗

难翻译机器码

#21


引用 19 楼 lactoferrin 的回复:
如果我搞一个东西半天搞不出来我就不搞了

有用过IDA的强人吗 ,帮个忙看看
我和你不同

#22


给你举个例子

int a;

int main()
{
a=1;
return 0;
}
你在exe文件中是看不到1的,a那个位置要么没分配要么是0,要知道a=1只能看代码

#23


引用 22 楼 lactoferrin 的回复:
给你举个例子

int a;

int main()
{
a=1;
return 0;
}
你在exe文件中是看不到1的,a那个位置要么没分配要么是0,要知道a=1只能看代码

嗯 

我动态调试下去看看

#24


引用 23 楼 dengchaozhu 的回复:
引用 22 楼 lactoferrin 的回复:
给你举个例子

int a;

int main()
{
a=1;
return 0;
}
你在exe文件中是看不到1的,a那个位置要么没分配要么是0,要知道a=1只能看代码

嗯 

我动态调试下去看看

其实 我搞的问题 网上已经有公布方法了 想自己动手看看 是否能找出

想你帮看看三个函数 是为什么

#25


NTSTATUS My_RecoveryHook_NtReadAndWriteMemory()//枚举找到目标模块

BYTE  Push1Ch[2]  = {0x6a,0x1c};   
//BYTE  PushAdd[5]  = {0x68,0x12,0x34,0x56,0x78};   
BYTE  PushAdd_ReadMemory[5]  = {0x68,0xd8,0xa4,0x4d,0x80}; 
BYTE  PushAdd_WriteMemory[5] = {0x68,0xf0,0xa4,0x4d,0x80}; 
KIRQL  Irql; 
BYTE  *NtReadVirtualMemoryAddress    = NULL;  
BYTE  *NtWriteVirtualMemoryAddress  = NULL;   

NtReadVirtualMemoryAddress = (BYTE*)myGetCurrentAddress(0xBA); 
if (NtReadVirtualMemoryAddress == NULL) 

KdPrint(("Failed to get address of NtReadVirtualMemory! \n")); 
return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES; 

NtWriteVirtualMemoryAddress = (BYTE*)myGetCurrentAddress(0x115); 
if (NtWriteVirtualMemoryAddress == NULL) 

KdPrint(("Failed to get address of NtWriteVirtualMemory! \n")); 
return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES; 



WPOFF();  
Irql=KeRaiseIrqlToDpcLevel(); 
RtlCopyMemory(NtReadVirtualMemoryAddress,Push1Ch,2); 
RtlCopyMemory(NtReadVirtualMemoryAddress+2,PushAdd_ReadMemory,5); 

RtlCopyMemory(NtWriteVirtualMemoryAddress,Push1Ch,2); 
RtlCopyMemory(NtWriteVirtualMemoryAddress+2,PushAdd_WriteMemory,5); 
KeLowerIrql(Irql); 
WPON();     

return  STATUS_SUCCESS; 


BYTE *g_pTesSafeAddress = NULL; 
ULONG g_TesSafeSize = 0; 
NTSTATUS GetTesSafeAddress(BYTE **ppAddress, ULONG *pSize) 

NTSTATUS status = STATUS_UNSUCCESSFUL; 
if ( g_pTesSafeAddress == NULL ) 

status = MyEnumKernelModule("\\??\\c:\\windows\\system32\\tessafe.sys", &(ULONG)g_pTesSafeAddress, &g_TesSafeSize); 
if (!NT_SUCCESS(status)) 

DbgPrint("TesSafe is not loaded yet\n"); 
return status; 


else 

*ppAddress = g_pTesSafeAddress; 
*pSize = g_TesSafeSize; 


return STATUS_SUCCESS; 

//里面貌似有个空指针 会蓝屏
NTSTATUS My_Recovery_Debugport() 

BYTE  *sd1 = NULL,*sd2 = NULL,*pd = NULL; 
BYTE  *p; 
KIRQL  Irql; 
BYTE  C390[2] = {0xc3,0x90}; 
NTSTATUS status = STATUS_UNSUCCESSFUL; 
BYTE *pTesSafeAddress = NULL; 
ULONG lTesSafeSize = 0; 
ULONG i = 0, number = 0; 

if ( !NT_SUCCESS(GetTesSafeAddress(&pTesSafeAddress, &lTesSafeSize)) ) 

return FAILED_TO_OBTAIN_FUNCTION_ADDRESSES; 


p = pTesSafeAddress + 20; 
for (i = 0; i < lTesSafeSize - 20; i++,p++) 

if ((*(p-1) == 0x18) && 
(*(p-2) == 0x87) && 
(*(p-3) == 0xDB) && 
(*(p-4) == 0x33) && 
(*(p-5) == 0x07) && 
(*(p-6) == 0x03) && 
(*p    == 0x33) && 
(*(p+1) == 0xC0) && 
(*(p+7) == 0x3B) && 
(*(p+8) == 0xD8) ) 

KdPrint(("--SD1 -- %0X \n",(ULONG)p)); 
sd1 = p; 
number += 1;  

if ((*(p-1) == 0x07) && 
(*(p-2) == 0x87) && 
(*(p-3) == 0xC0) && 
(*(p-4) == 0x33) && 
(*(p+14)== 0x89) && 
(*(p+15)== 0x1C) && 
(*(p+16)== 0x38) && 
(*p    == 0xA1)) 

KdPrint(("--SD2 -- %0X \n",(ULONG)p)); 
sd2 = p; 
number += 1;   

if ((*(p-2) == 0xE3) && 
(*(p-3) == 0xC1) && 
(*(p-7) == 0xF3) && 
(*(p-8) == 0x33) && 
(*(p-10)== 0xEB) && 
(*(p-11)== 0xC1) && 
(*(p+1) == 0xF3) && 
(*(p+2) == 0x42) && 
(*(p+3) == 0x3B) && 
(*(p+4) == 0xD1) && 
(*p    == 0x33)) 

KdPrint(("--PD -- %0X \n",(ULONG)p)); 
pd = p; 
number+=1;  

if (number >= 3) 

KdPrint(("number %d ---quit\n",number)); 
break; 



while (1) 

if ((*(pd-1) == 0xcc) && (*(pd-2) == 0xcc)) 

KdPrint(("pd address:%0X \n",(ULONG)pd)); 
WPOFF();  
Irql=KeRaiseIrqlToDpcLevel(); 
RtlCopyMemory(pd,C390,2); 
KeLowerIrql(Irql); 
WPON();     
break; 

pd--; 

while (1) 

if ((*(sd1-1) == 0xcc) && (*(sd1-2) == 0xcc)) 

KdPrint(("sd1 address:%0X \n",(ULONG)sd1)); 
WPOFF();   
Irql=KeRaiseIrqlToDpcLevel(); 
RtlCopyMemory(sd1,C390,2); 
KeLowerIrql(Irql); 
WPON();     
break; 

sd1--; 

while (1) 

if ((*(sd2-1) == 0xcc) && (*(sd2-2) == 0xcc)) 

KdPrint(("sd2 address:%0X \n",(ULONG)sd2)); 
WPOFF();  
Irql=KeRaiseIrqlToDpcLevel(); 
RtlCopyMemory(sd2,C390,2); 
KeLowerIrql(Irql); 
WPON();    
break; 

sd2--; 


return  STATUS_SUCCESS; 
}


我不明白它问什么用BYTE 
#define BYTE unsigned char 
而且我加载了驱动它也DbgPrint 没加载驱动


自己改写枚举内核模块函数 打印出来 所以GetTesSafeAddress 调用MyEnumKernelModule第一个参数是对的

#26


额 马甲

第一个函数COPY错了

NTSTATUS MyEnumKernelModule(IN CHAR* str,OUT ULONG *moduleadd,OUT ULONG *modulesie) 

NTSTATUS status = STATUS_SUCCESS; 
ULONG   n       = 0; 
ULONG   i       = 0; 
PSYSTEM_MODULE_INFORMATION_ENTRY   module = NULL; 
PVOID   pbuftmp = NULL; 
ANSI_STRING    ModuleName1,ModuleName2; 
BOOLEAN  tlgstst= FALSE;  

status = ZwQuerySystemInformation(11, &n, 0, &n); 

pbuftmp = ExAllocatePool(NonPagedPool, n); 

status = ZwQuerySystemInformation(11, pbuftmp, n, NULL); 

module = (PSYSTEM_MODULE_INFORMATION_ENTRY)((PULONG )pbuftmp + 1 ); 

RtlInitAnsiString(&ModuleName1,str); 
// 
n       = *((PULONG)pbuftmp ); 
for ( i = 0; i < n; i++ ) 

RtlInitAnsiString(&ModuleName2,(PCSZ)&module->ImageName); 
if (RtlCompareString(&ModuleName1,&ModuleName2,TRUE) == 0) 

DbgPrint("MyEnumKernelModule:%s:%0X \n",ModuleName2.Buffer,module->Base); 
*moduleadd  = (ULONG)module->Base; 
*modulesie  = module->Size; 
tlgstst = TRUE; 
break; 


ExFreePool(pbuftmp); 
if (tlgstst == FALSE) 

return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES; 

return status; 

有空帮我看看吧

这三个函数的意思应该是

找到指定驱动的BASE后 机器码搜索 找到指定地址后 RtlCopyMemory C3 90 进去

不明白

它找到了 Base后为什么+20

它为什么用BYTE呢 ULONG 没影响吧

#27


引用 22 楼 lactoferrin 的回复:

不理前面的问题了

列宁同志 帮我看看吧 我将三个函数简化了

BOOLEAN MyEnumKernelModule(IN CHAR* str,OUT ULONG *moduleadd,ULONG *ModuleSize) 

NTSTATUS status = STATUS_SUCCESS;
BOOLEAN  tlgstst= FALSE; 
ULONG   n       = 0; 
ULONG   i       = 0; 
PSYSTEM_MODULE_INFORMATION_ENTRY   module = NULL; 
PVOID   pbuftmp = NULL; 
ANSI_STRING    ModuleName1,ModuleName2; 


status = ZwQuerySystemInformation(SystemModuleInformation, &n, 0, &n); //获取大小

pbuftmp = ExAllocatePool(NonPagedPool, n);  //分配内存

status = ZwQuerySystemInformation(11, pbuftmp, n, NULL); //再次枚举 

module = (PSYSTEM_MODULE_INFORMATION_ENTRY)((PULONG )pbuftmp + 1 ); //赋值

RtlInitAnsiString(&ModuleName1,str);  
// 
n       = *((PULONG)pbuftmp ); 
for ( i = 0; i < n; i++ ) 

RtlInitAnsiString(&ModuleName2,(PCSZ)&module[i].ImageName); 

if (RtlCompareString(&ModuleName1,&ModuleName2,TRUE) == 0) 


KdPrint(("Name: %s Base:%x\n",ModuleName2.Buffer,module[i].Base));

*moduleadd = (ULONG)module[i].Base;
*ModuleSize=module[i].Size;
tlgstst = TRUE; 
break;


 
ExFreePool(pbuftmp);
return tlgstst;


BOOLEAN MyEnumTesSafe(ULONG *pAddr,ULONG *size)
{
BOOLEAN Result=FALSE;

if(MyEnumKernelModule("\\SystemRoot\\System32\\Drivers\\HTTP.sys",pAddr,size))
{
return TRUE;
}
return Result;

}
void AnitTesSafeReStart()
{

ULONG TesSafeAddr;
ULONG ModuleSize;
BYTE Data[]={0xFF};

//////////////////////////////////////////////////////////////////////////
if(FALSE==MyEnumTesSafe(&TesSafeAddr,&ModuleSize))
{
KdPrint(("没加载目标驱动!\n"));
return ;
}
if (((BYTE)(ULONG*)TesSafeAddr) == 0xFF) //关键
{
KdPrint((" OK \n",));
}


//////////////////////////////////////////////////////////////////////////


}

while(1)
   {
     if(TesSafe+1 == 0xFF)
     {
       DbgPrint("找到特征码");
       Break;
     }
   }
机器码搜索定位位置

标签 关键那里是判断不成功的 帮我看看啦 

#28


到底哪个是搜索特征码的

#29


引用 28 楼 lactoferrin 的回复:
到底哪个是搜索特征码的


    if (((BYTE)(ULONG*)TesSafeAddr) == 0xFF) //关键
    {
        KdPrint((" OK \n",));
    }
判断机器码是不是0xFF 但判断不成功

#30


你的TesSafeAddr是那个模块的基地址,pe文件开头的字节都是0x4d,不会是0xff

#31


引用 30 楼 lactoferrin 的回复:
你的TesSafeAddr是那个模块的基地址,pe文件开头的字节都是0x4d,不会是0xff

RtlCopyMemort 0XFF 进去了

还是无法判断 语句有错误吗

#32


你这代码不是搜索特征码,就是判断那个模块的第一字节是不是0xff,但这是不可能的,你硬往那里写一个0xff是自欺欺人

#33


引用 32 楼 lactoferrin 的回复:
你这代码不是搜索特征码,就是判断那个模块的第一字节是不是0xff,但这是不可能的,你硬往那里写一个0xff是自欺欺人

不是 测试下啊

我可以不写入个0xFF 那就判断是否0x4D

如果判断成功的话 那就开始循环寻找

#34


你把那里的东西打印出来

#35


循环查找
while

if (TesSafeAddr+i ==0x特征码)
{
  .......
}
 i++;

#36


你第一个查找的条件是什么

#37


引用 36 楼 lactoferrin 的回复:
你第一个查找的条件是什么

int i=0;
while(1)
{
    if (((BYTE)(ULONG*)TesSafeAddr+i) == 0xFF) //关键
    {
        KdPrint((" 找到 \n",));
        Break;
    }
    i++;

}
意思的大概是这样
如果没找到就下一个 没找到再下一个 一直找到0xFF为止

#38


那你发while(1)
  {
  if(TesSafe+1 == 0xFF)
  {
  DbgPrint("找到特征码");
  Break;
  }
  }干什么

#39


引用 38 楼 lactoferrin 的回复:
那你发while(1)
  {
  if(TesSafe+1 == 0xFF)
  {
  DbgPrint("找到特征码");
  Break;
  }
  }干什么

想让你大概的明白意思而已 可以当我没写过啦

回到上面

    if (((BYTE)(ULONG*)TesSafeAddr) == 0xFF) //无法判断机器码 是否那里有错了
    {
        KdPrint((" OK \n",));
    }

#40


这个更没用

#41


引用 40 楼 lactoferrin 的回复:
这个更没用

什么意思?

你是不是还在疑问我为什么判断 0xFF?

这样好了
 if (((BYTE)(ULONG*)TesSafeAddr) == 0x4D) //无法判断 是否那里有错了
  {
  KdPrint((" OK \n",));
  }
是不是((BYTE)(ULONG*)TesSafeAddr) 写错了?

#42


 if (*(BYTE*)TesSafeAddr == 0x4D) //无法判断 是否那里有错了
  {
  KdPrint((" OK \n",));
  }

#43


引用 42 楼 lactoferrin 的回复:
if (*(BYTE*)TesSafeAddr == 0x4D) //无法判断 是否那里有错了
  {
  KdPrint((" OK \n",));
  }


if (*(BYTE*)TesSafeAddr == 0x4D) 
{
KdPrint((" 判断成功!! \n"));
}

这样会导致蓝屏!

#44


引用 42 楼 lactoferrin 的回复:
if (*(BYTE*)TesSafeAddr == 0x4D) //无法判断 是否那里有错了
  {
  KdPrint((" OK \n",));
  }

我错了。。

多谢列宁!

#45


可以参考MSDN例子pwalk中代码

#46


引用 45 楼 zhao4zhong1 的回复:
可以参考MSDN例子pwalk中代码

e文不好 很少看MSDN 呵呵 都是BAIDU GOOGLE

#1


对啊 我记得汇编里 ;后面的是注释
为什么呢 IDA没把数据显示出来?
有用过IDA的强人吗 ,帮个忙看看

#2


LZ的头像a

#3


只是分配一些空间用,其初始值没有意义。

#4


引用 3 楼 zhao4zhong1 的回复:
只是分配一些空间用,其初始值没有意义。

未初始化的变量
第二个问题是
IDA开始地址 10001
10010  mov eax,eax

枚举内核模块 找到目标驱动的Base +10

这样吗 昨晚临睡前想想 好像是这样 呵呵

#5


引用 2 楼 zhoutanliang 的回复:
LZ的头像a

头像怎么了

#6


炯炯有神!

#7


引用 6 楼 zhao4zhong1 的回复:
炯炯有神!

呵呵 

是吗

我的第二个问题啊


IDA显示的:

第一条语句的地址是 10001
mov eax,eax 地址是10010
驱动基址+(10010-10001) =mov eax,eax的地址

#8


有没有源代码?有的话加int 3 断点。

没有的话,使用文件偏移-->内存偏移 转换。

#9


引用 8 楼 mydo 的回复:
有没有源代码?有的话加int 3 断点。

没有的话,使用文件偏移-->内存偏移 转换。

当然不是我自己的驱动

"使用文件偏移-->内存偏移 转换"此句怎么解?

#10


哪位可以告诉我方法

使用文件偏移-->内存偏移


有用过IDA的强人吗 ,帮个忙看看
将图上的01001026转到内存地址怎么计算的?

#11


怎么沉了 自己UP下

#12


IDA的问题还是去看雪吧

#13


引用 12 楼 wodemuyecun 的回复:
IDA的问题还是去看雪吧

看雪全都潜水 没个回答... 

#14


这个可能是运行后才赋值

#15


你是不是走火入魔了,不要把有限的生命浪费在无限的加密解密死循环中!

#16


引用 15 楼 lactoferrin 的回复:
你是不是走火入魔了,不要把有限的生命浪费在无限的加密解密死循环中!

才没!
我想解决个DebugPort清零
我用IDA找到它清零的地方了 我想把它在内存NOP掉

#17


引用 15 楼 lactoferrin 的回复:
你是不是走火入魔了,不要把有限的生命浪费在无限的加密解密死循环中!


列宁同志可以教下我吗 在IDA里面的地址转到内存地址

对啊 都搞了这么久了 
速度搞定干别的去

#18


ida是静态分析,你这里看起来是运行后再分配的位置,只有运行后才能看得到

#19


如果我搞一个东西半天搞不出来我就不搞了

#20


引用 18 楼 lactoferrin 的回复:
ida是静态分析,你这里看起来是运行后再分配的位置,只有运行后才能看得到

难道要机器码搜索吗

难翻译机器码

#21


引用 19 楼 lactoferrin 的回复:
如果我搞一个东西半天搞不出来我就不搞了

有用过IDA的强人吗 ,帮个忙看看
我和你不同

#22


给你举个例子

int a;

int main()
{
a=1;
return 0;
}
你在exe文件中是看不到1的,a那个位置要么没分配要么是0,要知道a=1只能看代码

#23


引用 22 楼 lactoferrin 的回复:
给你举个例子

int a;

int main()
{
a=1;
return 0;
}
你在exe文件中是看不到1的,a那个位置要么没分配要么是0,要知道a=1只能看代码

嗯 

我动态调试下去看看

#24


引用 23 楼 dengchaozhu 的回复:
引用 22 楼 lactoferrin 的回复:
给你举个例子

int a;

int main()
{
a=1;
return 0;
}
你在exe文件中是看不到1的,a那个位置要么没分配要么是0,要知道a=1只能看代码

嗯 

我动态调试下去看看

其实 我搞的问题 网上已经有公布方法了 想自己动手看看 是否能找出

想你帮看看三个函数 是为什么

#25


NTSTATUS My_RecoveryHook_NtReadAndWriteMemory()//枚举找到目标模块

BYTE  Push1Ch[2]  = {0x6a,0x1c};   
//BYTE  PushAdd[5]  = {0x68,0x12,0x34,0x56,0x78};   
BYTE  PushAdd_ReadMemory[5]  = {0x68,0xd8,0xa4,0x4d,0x80}; 
BYTE  PushAdd_WriteMemory[5] = {0x68,0xf0,0xa4,0x4d,0x80}; 
KIRQL  Irql; 
BYTE  *NtReadVirtualMemoryAddress    = NULL;  
BYTE  *NtWriteVirtualMemoryAddress  = NULL;   

NtReadVirtualMemoryAddress = (BYTE*)myGetCurrentAddress(0xBA); 
if (NtReadVirtualMemoryAddress == NULL) 

KdPrint(("Failed to get address of NtReadVirtualMemory! \n")); 
return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES; 

NtWriteVirtualMemoryAddress = (BYTE*)myGetCurrentAddress(0x115); 
if (NtWriteVirtualMemoryAddress == NULL) 

KdPrint(("Failed to get address of NtWriteVirtualMemory! \n")); 
return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES; 



WPOFF();  
Irql=KeRaiseIrqlToDpcLevel(); 
RtlCopyMemory(NtReadVirtualMemoryAddress,Push1Ch,2); 
RtlCopyMemory(NtReadVirtualMemoryAddress+2,PushAdd_ReadMemory,5); 

RtlCopyMemory(NtWriteVirtualMemoryAddress,Push1Ch,2); 
RtlCopyMemory(NtWriteVirtualMemoryAddress+2,PushAdd_WriteMemory,5); 
KeLowerIrql(Irql); 
WPON();     

return  STATUS_SUCCESS; 


BYTE *g_pTesSafeAddress = NULL; 
ULONG g_TesSafeSize = 0; 
NTSTATUS GetTesSafeAddress(BYTE **ppAddress, ULONG *pSize) 

NTSTATUS status = STATUS_UNSUCCESSFUL; 
if ( g_pTesSafeAddress == NULL ) 

status = MyEnumKernelModule("\\??\\c:\\windows\\system32\\tessafe.sys", &(ULONG)g_pTesSafeAddress, &g_TesSafeSize); 
if (!NT_SUCCESS(status)) 

DbgPrint("TesSafe is not loaded yet\n"); 
return status; 


else 

*ppAddress = g_pTesSafeAddress; 
*pSize = g_TesSafeSize; 


return STATUS_SUCCESS; 

//里面貌似有个空指针 会蓝屏
NTSTATUS My_Recovery_Debugport() 

BYTE  *sd1 = NULL,*sd2 = NULL,*pd = NULL; 
BYTE  *p; 
KIRQL  Irql; 
BYTE  C390[2] = {0xc3,0x90}; 
NTSTATUS status = STATUS_UNSUCCESSFUL; 
BYTE *pTesSafeAddress = NULL; 
ULONG lTesSafeSize = 0; 
ULONG i = 0, number = 0; 

if ( !NT_SUCCESS(GetTesSafeAddress(&pTesSafeAddress, &lTesSafeSize)) ) 

return FAILED_TO_OBTAIN_FUNCTION_ADDRESSES; 


p = pTesSafeAddress + 20; 
for (i = 0; i < lTesSafeSize - 20; i++,p++) 

if ((*(p-1) == 0x18) && 
(*(p-2) == 0x87) && 
(*(p-3) == 0xDB) && 
(*(p-4) == 0x33) && 
(*(p-5) == 0x07) && 
(*(p-6) == 0x03) && 
(*p    == 0x33) && 
(*(p+1) == 0xC0) && 
(*(p+7) == 0x3B) && 
(*(p+8) == 0xD8) ) 

KdPrint(("--SD1 -- %0X \n",(ULONG)p)); 
sd1 = p; 
number += 1;  

if ((*(p-1) == 0x07) && 
(*(p-2) == 0x87) && 
(*(p-3) == 0xC0) && 
(*(p-4) == 0x33) && 
(*(p+14)== 0x89) && 
(*(p+15)== 0x1C) && 
(*(p+16)== 0x38) && 
(*p    == 0xA1)) 

KdPrint(("--SD2 -- %0X \n",(ULONG)p)); 
sd2 = p; 
number += 1;   

if ((*(p-2) == 0xE3) && 
(*(p-3) == 0xC1) && 
(*(p-7) == 0xF3) && 
(*(p-8) == 0x33) && 
(*(p-10)== 0xEB) && 
(*(p-11)== 0xC1) && 
(*(p+1) == 0xF3) && 
(*(p+2) == 0x42) && 
(*(p+3) == 0x3B) && 
(*(p+4) == 0xD1) && 
(*p    == 0x33)) 

KdPrint(("--PD -- %0X \n",(ULONG)p)); 
pd = p; 
number+=1;  

if (number >= 3) 

KdPrint(("number %d ---quit\n",number)); 
break; 



while (1) 

if ((*(pd-1) == 0xcc) && (*(pd-2) == 0xcc)) 

KdPrint(("pd address:%0X \n",(ULONG)pd)); 
WPOFF();  
Irql=KeRaiseIrqlToDpcLevel(); 
RtlCopyMemory(pd,C390,2); 
KeLowerIrql(Irql); 
WPON();     
break; 

pd--; 

while (1) 

if ((*(sd1-1) == 0xcc) && (*(sd1-2) == 0xcc)) 

KdPrint(("sd1 address:%0X \n",(ULONG)sd1)); 
WPOFF();   
Irql=KeRaiseIrqlToDpcLevel(); 
RtlCopyMemory(sd1,C390,2); 
KeLowerIrql(Irql); 
WPON();     
break; 

sd1--; 

while (1) 

if ((*(sd2-1) == 0xcc) && (*(sd2-2) == 0xcc)) 

KdPrint(("sd2 address:%0X \n",(ULONG)sd2)); 
WPOFF();  
Irql=KeRaiseIrqlToDpcLevel(); 
RtlCopyMemory(sd2,C390,2); 
KeLowerIrql(Irql); 
WPON();    
break; 

sd2--; 


return  STATUS_SUCCESS; 
}


我不明白它问什么用BYTE 
#define BYTE unsigned char 
而且我加载了驱动它也DbgPrint 没加载驱动


自己改写枚举内核模块函数 打印出来 所以GetTesSafeAddress 调用MyEnumKernelModule第一个参数是对的

#26


额 马甲

第一个函数COPY错了

NTSTATUS MyEnumKernelModule(IN CHAR* str,OUT ULONG *moduleadd,OUT ULONG *modulesie) 

NTSTATUS status = STATUS_SUCCESS; 
ULONG   n       = 0; 
ULONG   i       = 0; 
PSYSTEM_MODULE_INFORMATION_ENTRY   module = NULL; 
PVOID   pbuftmp = NULL; 
ANSI_STRING    ModuleName1,ModuleName2; 
BOOLEAN  tlgstst= FALSE;  

status = ZwQuerySystemInformation(11, &n, 0, &n); 

pbuftmp = ExAllocatePool(NonPagedPool, n); 

status = ZwQuerySystemInformation(11, pbuftmp, n, NULL); 

module = (PSYSTEM_MODULE_INFORMATION_ENTRY)((PULONG )pbuftmp + 1 ); 

RtlInitAnsiString(&ModuleName1,str); 
// 
n       = *((PULONG)pbuftmp ); 
for ( i = 0; i < n; i++ ) 

RtlInitAnsiString(&ModuleName2,(PCSZ)&module->ImageName); 
if (RtlCompareString(&ModuleName1,&ModuleName2,TRUE) == 0) 

DbgPrint("MyEnumKernelModule:%s:%0X \n",ModuleName2.Buffer,module->Base); 
*moduleadd  = (ULONG)module->Base; 
*modulesie  = module->Size; 
tlgstst = TRUE; 
break; 


ExFreePool(pbuftmp); 
if (tlgstst == FALSE) 

return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES; 

return status; 

有空帮我看看吧

这三个函数的意思应该是

找到指定驱动的BASE后 机器码搜索 找到指定地址后 RtlCopyMemory C3 90 进去

不明白

它找到了 Base后为什么+20

它为什么用BYTE呢 ULONG 没影响吧

#27


引用 22 楼 lactoferrin 的回复:

不理前面的问题了

列宁同志 帮我看看吧 我将三个函数简化了

BOOLEAN MyEnumKernelModule(IN CHAR* str,OUT ULONG *moduleadd,ULONG *ModuleSize) 

NTSTATUS status = STATUS_SUCCESS;
BOOLEAN  tlgstst= FALSE; 
ULONG   n       = 0; 
ULONG   i       = 0; 
PSYSTEM_MODULE_INFORMATION_ENTRY   module = NULL; 
PVOID   pbuftmp = NULL; 
ANSI_STRING    ModuleName1,ModuleName2; 


status = ZwQuerySystemInformation(SystemModuleInformation, &n, 0, &n); //获取大小

pbuftmp = ExAllocatePool(NonPagedPool, n);  //分配内存

status = ZwQuerySystemInformation(11, pbuftmp, n, NULL); //再次枚举 

module = (PSYSTEM_MODULE_INFORMATION_ENTRY)((PULONG )pbuftmp + 1 ); //赋值

RtlInitAnsiString(&ModuleName1,str);  
// 
n       = *((PULONG)pbuftmp ); 
for ( i = 0; i < n; i++ ) 

RtlInitAnsiString(&ModuleName2,(PCSZ)&module[i].ImageName); 

if (RtlCompareString(&ModuleName1,&ModuleName2,TRUE) == 0) 


KdPrint(("Name: %s Base:%x\n",ModuleName2.Buffer,module[i].Base));

*moduleadd = (ULONG)module[i].Base;
*ModuleSize=module[i].Size;
tlgstst = TRUE; 
break;


 
ExFreePool(pbuftmp);
return tlgstst;


BOOLEAN MyEnumTesSafe(ULONG *pAddr,ULONG *size)
{
BOOLEAN Result=FALSE;

if(MyEnumKernelModule("\\SystemRoot\\System32\\Drivers\\HTTP.sys",pAddr,size))
{
return TRUE;
}
return Result;

}
void AnitTesSafeReStart()
{

ULONG TesSafeAddr;
ULONG ModuleSize;
BYTE Data[]={0xFF};

//////////////////////////////////////////////////////////////////////////
if(FALSE==MyEnumTesSafe(&TesSafeAddr,&ModuleSize))
{
KdPrint(("没加载目标驱动!\n"));
return ;
}
if (((BYTE)(ULONG*)TesSafeAddr) == 0xFF) //关键
{
KdPrint((" OK \n",));
}


//////////////////////////////////////////////////////////////////////////


}

while(1)
   {
     if(TesSafe+1 == 0xFF)
     {
       DbgPrint("找到特征码");
       Break;
     }
   }
机器码搜索定位位置

标签 关键那里是判断不成功的 帮我看看啦 

#28


到底哪个是搜索特征码的

#29


引用 28 楼 lactoferrin 的回复:
到底哪个是搜索特征码的


    if (((BYTE)(ULONG*)TesSafeAddr) == 0xFF) //关键
    {
        KdPrint((" OK \n",));
    }
判断机器码是不是0xFF 但判断不成功

#30


你的TesSafeAddr是那个模块的基地址,pe文件开头的字节都是0x4d,不会是0xff

#31


引用 30 楼 lactoferrin 的回复:
你的TesSafeAddr是那个模块的基地址,pe文件开头的字节都是0x4d,不会是0xff

RtlCopyMemort 0XFF 进去了

还是无法判断 语句有错误吗

#32


你这代码不是搜索特征码,就是判断那个模块的第一字节是不是0xff,但这是不可能的,你硬往那里写一个0xff是自欺欺人

#33


引用 32 楼 lactoferrin 的回复:
你这代码不是搜索特征码,就是判断那个模块的第一字节是不是0xff,但这是不可能的,你硬往那里写一个0xff是自欺欺人

不是 测试下啊

我可以不写入个0xFF 那就判断是否0x4D

如果判断成功的话 那就开始循环寻找

#34


你把那里的东西打印出来

#35


循环查找
while

if (TesSafeAddr+i ==0x特征码)
{
  .......
}
 i++;

#36


你第一个查找的条件是什么

#37


引用 36 楼 lactoferrin 的回复:
你第一个查找的条件是什么

int i=0;
while(1)
{
    if (((BYTE)(ULONG*)TesSafeAddr+i) == 0xFF) //关键
    {
        KdPrint((" 找到 \n",));
        Break;
    }
    i++;

}
意思的大概是这样
如果没找到就下一个 没找到再下一个 一直找到0xFF为止

#38


那你发while(1)
  {
  if(TesSafe+1 == 0xFF)
  {
  DbgPrint("找到特征码");
  Break;
  }
  }干什么

#39


引用 38 楼 lactoferrin 的回复:
那你发while(1)
  {
  if(TesSafe+1 == 0xFF)
  {
  DbgPrint("找到特征码");
  Break;
  }
  }干什么

想让你大概的明白意思而已 可以当我没写过啦

回到上面

    if (((BYTE)(ULONG*)TesSafeAddr) == 0xFF) //无法判断机器码 是否那里有错了
    {
        KdPrint((" OK \n",));
    }

#40


这个更没用

#41


引用 40 楼 lactoferrin 的回复:
这个更没用

什么意思?

你是不是还在疑问我为什么判断 0xFF?

这样好了
 if (((BYTE)(ULONG*)TesSafeAddr) == 0x4D) //无法判断 是否那里有错了
  {
  KdPrint((" OK \n",));
  }
是不是((BYTE)(ULONG*)TesSafeAddr) 写错了?

#42


 if (*(BYTE*)TesSafeAddr == 0x4D) //无法判断 是否那里有错了
  {
  KdPrint((" OK \n",));
  }

#43


引用 42 楼 lactoferrin 的回复:
if (*(BYTE*)TesSafeAddr == 0x4D) //无法判断 是否那里有错了
  {
  KdPrint((" OK \n",));
  }


if (*(BYTE*)TesSafeAddr == 0x4D) 
{
KdPrint((" 判断成功!! \n"));
}

这样会导致蓝屏!

#44


引用 42 楼 lactoferrin 的回复:
if (*(BYTE*)TesSafeAddr == 0x4D) //无法判断 是否那里有错了
  {
  KdPrint((" OK \n",));
  }

我错了。。

多谢列宁!

#45


可以参考MSDN例子pwalk中代码

#46


引用 45 楼 zhao4zhong1 的回复:
可以参考MSDN例子pwalk中代码

e文不好 很少看MSDN 呵呵 都是BAIDU GOOGLE