今天继续来玩Windbg script。在写复杂的脚本的时候,可能需要根据调试的环境,指定不同的脚本代码来运行。而Windbg貌似没有提供很好的方式,让脚本得知调试环境。还好,我们可以用一些其他的方式获得这些信息,例如:写一个扩展程序来设置这些信息到Aliase上,0cchext就实现了这个功能。另外一个方式就是使用脚本自身来获得一些简单的信息,算是个windbg script中的小把戏吧。脚本如下:

$$ Initialize script environment
$$ Author: nighxie 
$$ Blog: 0cch.net
$$ @#NtMajorVersion @#NtMinorVersion - System version number.
$$ @#DebugMode - 0:kd 1:lkd 2:user

ad /q ${/v:$sharedata} 

.catch {
    .foreach /pS 2 (${/v:$addr} {!kuser}) {
        aS ${/v:$sharedata} ${$addr};
        .leave;
    }
}

.block {
    r @$t0=${$sharedata};
    aS /x ${/v:@#NtMajorVersion} @@C++(((nt!_KUSER_SHARED_DATA *)@$t0)->NtMajorVersion);
    aS /x ${/v:@#NtMinorVersion} @@C++(((nt!_KUSER_SHARED_DATA *)@$t0)->NtMinorVersion);
}

ad /q ${/v:$sharedata} 

.catch {
    r @$t0 = 0;
    .foreach (${/v:$addr} {lm1m m nt}) {
        r @$t0 = ${$addr};
        .leave;
    }
}

.if ($vvalid(@$t0, 1)) {
    aS ${/v:@#DebugMode} 0;
     .foreach (${/v:$val} {.catch{? @eax}}) {
        .if ($scmp("${$val}", "\'@eax\'")==0) {
            aS ${/v:@#DebugMode} 1;
        }
    }
}
.else {
    aS ${/v:@#DebugMode} 2;
}