uty's blog

uty@uaty

My Links

Blog统计

文章

收藏

相册

分类1

存档


正在读取评论……
2008年12月03日

IsBadReadPtr Function Verifies that the calling process has read access to the specified range of memory. Important This function is obsolete and should not be used. Despite its name, it does not guarantee that the pointer is valid or that the memory pointed to is safe to use. For more information, see Remarks on this page. Syntax BOOL WINAPI IsBadReadPtr( __in const VOID *lp, __in UINT_PTR ucb ); Parameters lp [in] A pointer to the first byte of the memory block. ucb [in] The size of the memory block, in bytes. If this parameter is zero, the return value is zero. Return Value If the calling process has read access to all bytes in the specified memory range, the return value is zero. If the calling process does not have read access to all bytes in the specified memory range, the return value is nonzero. If the application is compiled as a debugging version, and the process does not have read access to all bytes in the specified memory range, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, and returns a nonzero value. This behavior is by design, as a debugging aid. Remarks This function is typically used when working with pointers returned from third-party libraries, where you cannot determine the memory management behavior in the third-party DLL. Threads in a process are expected to cooperate in such a way that one will not free memory that the other needs. Use of this function does not negate the need to do this. If this is not done, the application may fail in an unpredictable manner. Dereferencing potentially invalid pointers can disable stack expansion in other threads. A thread exhausting its stack, when stack expansion has been disabled, results in the immediate termination of the parent process, with no pop-up error window or diagnostic information. If the calling process has read access to some, but not all, of the bytes in the specified memory range, the return value is nonzero. In a preemptive multitasking environment, it is possible for some other thread to change the process's access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception. Requirements Minimum supported client Windows 2000 Professional Minimum supported server Windows 2000 Server Header Winbase.h (include Windows.h) Library Kernel32.lib DLL Kernel32.dll See Also IsBadCodePtr IsBadStringPtr IsBadWritePtr Send comments about this topic to Microsoft Build date: 11/6/2008 Tags : Add a tag Add Cancel Flag as ContentBug Community Content Add new content Annotations Raymond Chen (The Old New Thing) says: never ever use this function Peter Smith in Redmond | Edit | Show History Please Wait Via Raymond Chen's "The Old New Thing" blog, http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx IsBadXxxPtr should really be called CrashProgramRandomly Often I'll see code that tries to "protect" against invalid pointer parameters. This is usually done by calling a function like IsBadWritePtr. But this is a bad idea. IsBadWritePtr should really be called CrashProgramRandomly. The documentation for the IsBadXxxPtr functions presents the technical reasons why, but I'm going to dig a little deeper. For one thing, if the "bad pointer" points into a guard page, then probing the memory will raise a guard page exception. The IsBadXxxPtr function will catch the exception and return "not a valid pointer". But guard page exceptions are raised only once. You just blew your one chance. When the code that is managing the guard page accesses the memory for what it thinks is the first time (but is really the second), it won't get the guard page exception but will instead get a normal access violation. Alternatively, it's possible that your function was called by some code that intentionally passed a pointer to a guard page (or a PAGE_NOACCESS page) and was expecting to receive that guard page exception or access violation exception so that it could dynamically generate the data that should go onto that page. (Simulation of large address spaces via pointer-swizzling is one scenario where this can happen.) Swallowing the exception in IsBadXxxPtr means that the caller's exception handler doesn't get a chance to run, which means that your code rejected a pointer that would actually have been okay, if only you had let the exception handler do its thing. "Yeah, but my code doesn't use guard pages or play games with PAGE_NOACCESS pages, so I don't care." Well, for one thing, just because your code doesn't use these features pages doesn't mean that no other code in your process uses them. One of the DLLs that you link to might use guard pages, and your use of IsBadXxxPtr to test a pointer into a guard page will break that other DLL. And second, your program does use guard pages; you just don't realize it. The dynamic growth of the stack is performed via guard pages: Just past the last valid page on the stack is a guard page. When the stack grows into the guard page, a guard page exception is raised, which the default exception handler handles by committing a new stack page and setting the next page to be a guard page. (I suspect this design was chosen in order to avoid having to commit the entire memory necessary for all thread stacks. Since the default thread stack size is a megabyte, this would have meant that a program with ten threads would commit ten megabytes of memory, even though each thread probably uses only 24KB of that commitment. When you have a small pagefile or are running without a pagefile entirely, you don't want to waste 97% of your commit limit on unused stack memory.) "But what should I do, then, if somebody passes me a bad pointer?" You should crash. No, really. In the Win32 programming model, exceptions are truly exceptional. As a general rule, you shouldn't try to catch them. And even if you decide you want to catch them, you need to be very careful that you catch exactly what you want and no more. Trying to intercept the invalid pointer and returning an error code creates nondeterministic behavior. Where do invalid pointers come from? Typically they are caused by programming errors. Using memory after freeing it, using uninitialized memory, that sort of thing. Consequently, an invalid pointer might actually point to valid memory, if for example the heap page that used to contain the memory has not been decomitted, or if the uninitialized memory contains a value that when reinterpreted as a pointer just happens to be a pointer to memory that is valid right now. On the other hand, it might point to truly invalid memory. If you use IsBadWritePtr to "validate" your pointers before writing to them, then in the case where it happens to point to memory that is valid, you end up corrupting memory (since the pointer is "valid" and you therefore decide to write to it). And in the case where it happens to point to an invalid address, you return an error code. In both cases, the program keeps on running, and then that memory corruption manifests itself as an "impossible" crash two hours later. In other words IsBadWritePtr is really CorruptMemoryIfPossible. It tries to corrupt memory, but if doing so raises an exception, it merely fails the operation. Many teams at Microsoft have rediscovered that IsBadXxxPtr causes bugs rather than fixes them. It's not fun getting a bucketful of crash dumps and finding that they are all of the "impossible" sort. You hunt through your code in search of this impossible bug. Maybe you find somebody who was using IsBadXxxPtr or equivalently an exception handler that swallows access violation exceptions and converts them to error codes. You remove the IsBadXxxPtr in order to let the exception escape unhandled and crash the program. Then you run the scenario again. And wow, look, the program crashes in that function, and when you debug it, you find the code that was, say, using a pointer after freeing it. That bug has been there for years, and it was manifesting itself as an "impossible" bug because the function was trying to be helpful by "validating" its pointers, when in fact what it was doing was taking a straightforward problem and turning it into an "impossible" bug. There is a subtlety to this advice that you should just crash when given invalid input, which I'll take up next time. Tags : Add a tag Add Cancel Flag as ContentBug | Edit Tags : Add a tag Add Cancel Flag as ContentBug Manage Your Profile | Legal | Contact Us | MSDN Flash Newsletter © 2008 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks | Privacy Statement


2008年12月01日


    摘要:kd> dd nt!NtCancelDeviceWakeupRequest 805bde0e 000002b8 0004c2c0 cccccccc 74a0cccc 805bde1e 2480559a 1ad8f603 c3c0fec0 cccccccc 805bde2e 1c6acccc 4daa1068 a2a4e880 a164fff7 805bde3e 00000124 0140808a db330000 3874c33a 805bde4e 8bfc5d89 b4a10c7d 3b80558b 890272f8 805bde5e 89078b18 fc4d8307 8b20ebff 008bec45 805bde6e 4589008b 40c033dc e8658bc3 fffc4d83 805bde7e e9dc458b 00000082 640c7d8b 000124a1 kd> u 805bde0e nt!NtModifyBootEntry: 805bde0e b8020000c0 mov eax,0C00000    (全文共759字)——点击此处阅读全文


2008年10月28日


    摘要:

三种链表是InLoadOrderModuleList , InMemoryOrderModuleList , InInitializationOrderModuleList

lkd> !peb
PEB at 7ffd5000
    InheritedAddressSpace:    No
    ReadImageFileExecOptions: No
    BeingDebugged:            No
    ImageBaseAddress:         01000000
    Ldr      (全文共6954字)——点击此处阅读全文



2008年07月22日

#ifndef _DISK_HIVE_SUBS_H_
#define _DISK_HIVE_SUBS_H_
//-----------------------------------------------------------------------------//
#define HIVE_SYSTEM	0
#define HIVE_SOFTWARE	1
//-----------------------------------------------------------------------------//
LONG
NIAPHiveOpenHive(
	IN  ULONG ulHive,
	OUT PHANDLE phFileHandle,
	OUT PHANDLE phFileMappingHandle,
	OUT PHANDLE phHiveHandle // hive file map base
	);

LONG
NIAPHiveCloseHive(
	IN HANDLE hFileHandle,
	IN HANDLE hFileMappingHandle,
	IN HANDLE hHiveHandle // hive file map base
	);

LONG
NIAPHiveOpenKey(
	IN  HANDLE  hHiveHandle,
	IN  PWCHAR  pwstrKeyPath,
	OUT PHANDLE phKeyHandle
	);

LONG
NIAPHiveQueryInfoKey(
	IN  HANDLE  hHiveHandle,
	IN  HANDLE  hKey,
	OUT PULONG  pulSubKeys OPTIONAL,
	OUT PULONG  pulValues OPTIONAL, 
	OUT PULONG  pulMaxNameLen OPTIONAL,
	OUT PULONG  pulMaxClassLen OPTIONAL,
	OUT PULONG  pulMaxValueNameLen OPTIONAL,
	OUT PULONG  pulMaxValueDataLen OPTIONAL
	);

LONG
NIAPHiveEnumKey(
	IN  HANDLE hHiveHandle,
	IN  HANDLE hKey,
	IN  ULONG  ulIndex,
	OUT PWCHAR pwstrName,
	IN  ULONG  ulNameSize
	);

LONG
NIAPHiveEnumValue(
	IN  HANDLE hHiveHandle,
	IN  HANDLE hKey,
	IN  ULONG ulIndex,
	OUT PWCHAR pwstrValueName,
	IN  PULONG pulValueNameSize,
	OUT PULONG pulType OPTIONAL,
	OUT PVOID pData OPTIONAL,
	IN OUT PULONG pulDataLen OPTIONAL
	);

LONG
NIAPHiveCloseKey(
	IN HANDLE hHiveHandle,
	IN HANDLE hKey
	);
//-----------------------------------------------------------------------------//
#endif

 

Example Code:

#include <Windows.h>
#include <stdio.h>
#include "diskhivesubs.h"
//-----------------------------------------------------------------------------//
int wmain(int argc, PWCHAR argv[])
{
	LONG lResult = -1;

	HANDLE hFileHandle = INVALID_HANDLE_VALUE;
	HANDLE hFileMappingHandle = INVALID_HANDLE_VALUE;
	HANDLE hHiveHandle = NULL;
	HANDLE hKeyHandle = INVALID_HANDLE_VALUE;

	ULONG  ulSubKeys = 0;
	ULONG  ulValues = 0;
	ULONG  ulMaxNameLen = 0;
	ULONG  ulMaxClassLen = 0;
	ULONG  ulMaxValueNameLen = 0;
	ULONG  ulMaxValueDataLen = 0;

	PWCHAR pwstrSubKeyNameBuffer = NULL;
	PWCHAR pwstrValueNameBuffer = NULL;
	ULONG ulValueNameSize = 0;

	HANDLE hStdOut = INVALID_HANDLE_VALUE;

	ULONG ulBytesWritten = 0;

	PVOID pValueData = NULL;
	ULONG ulValueDataLen = 0;

	ULONG i = 0;


	hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
	if (INVALID_HANDLE_VALUE == hStdOut)
	{
		goto Exit0;
	}

	lResult = NIAPHiveOpenHive(HIVE_SYSTEM, &hFileHandle, &hFileMappingHandle, &hHiveHandle);
	if (ERROR_SUCCESS != lResult)
	{
		goto Exit0;
	}

	lResult = NIAPHiveOpenKey(hHiveHandle, argv[1], &hKeyHandle);
	if (ERROR_SUCCESS != lResult)
	{
		printf("NIAPHiveOpenKey fail!\n");
		goto Exit0;
	}
	else
	{
		printf("NIAPHiveOpenKey success, ulKeyHandle 0x%x\n", (ULONG)hKeyHandle);
	}

	lResult = NIAPHiveQueryInfoKey(hHiveHandle, hKeyHandle,
		&ulSubKeys,
		&ulValues,
		&ulMaxNameLen,
		&ulMaxClassLen,
		&ulMaxValueNameLen,
		&ulMaxValueDataLen
		);

	if (ERROR_SUCCESS != lResult)
	{
		printf("NIAPHiveQueryInfoKey fail!\n");
	}
	else
	{
		printf("NIAPHiveQueryInfoKey success\n");
		printf("ulSubKeys: %d\n", ulSubKeys);
		printf("ulValues: %d\n", ulValues);
		printf("ulMaxNameLen: %d\n", ulMaxNameLen);
		printf("ulMaxClassLen: %d\n", ulMaxClassLen);
		printf("ulMaxValueNameLen: %d\n", ulMaxValueNameLen);
		printf("ulMaxValueDataLen: %d\n", ulMaxValueDataLen);
	}

	pwstrSubKeyNameBuffer = malloc(ulMaxNameLen + sizeof(UNICODE_NULL));
	if (NULL == pwstrSubKeyNameBuffer)
	{
		lResult = -1;
		goto Exit0;
	}
	memset(pwstrSubKeyNameBuffer, 0, ulMaxNameLen + sizeof(UNICODE_NULL));

	pwstrValueNameBuffer = malloc(ulMaxValueNameLen + sizeof(UNICODE_NULL));
	if (NULL == pwstrValueNameBuffer)
	{
		lResult = -1;
		goto Exit0;
	}
	memset(pwstrValueNameBuffer, 0, ulMaxValueNameLen + sizeof(UNICODE_NULL));

	for (i = 0; i < ulSubKeys; i++)
	{
		memset(pwstrSubKeyNameBuffer, 0, ulMaxNameLen + sizeof(UNICODE_NULL));
		lResult = NIAPHiveEnumKey(hHiveHandle, hKeyHandle, i, pwstrSubKeyNameBuffer, (ulMaxNameLen + sizeof(UNICODE_NULL)) / sizeof(WCHAR));
		if (ERROR_SUCCESS != lResult)
		{
			printf("NIAPHiveEnumKey fail!\n");
			goto Exit0;
		}
		WriteConsole( hStdOut, pwstrSubKeyNameBuffer, (ulMaxNameLen + sizeof(UNICODE_NULL)) / sizeof(WCHAR), &ulBytesWritten, NULL);
		WriteConsole( hStdOut, L"\n", 1, &ulBytesWritten, NULL);
	}

	printf("Value:\n");


	ulValueDataLen = ulMaxValueDataLen;

	pValueData = malloc(ulValueDataLen);
	if (NULL == pValueData)
	{
		lResult = -1;
		goto Exit0;
	}

	for (i = 0; i < ulValues; i++)
	{
		ULONG ulType = 0;

		ulValueDataLen = ulMaxValueDataLen;
		memset(pValueData, 0, ulValueDataLen);

		ulValueNameSize = (ulMaxValueNameLen + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
		memset(pwstrValueNameBuffer, 0, ulMaxValueNameLen + sizeof(UNICODE_NULL));
		lResult = NIAPHiveEnumValue(hHiveHandle, hKeyHandle, i, pwstrValueNameBuffer, &ulValueNameSize,
			                        &ulType, pValueData, &ulValueDataLen);
		if (ERROR_SUCCESS != lResult)
		{
			printf("NIAPHiveEnumValue fail, 0x%x\n", lResult);
			goto Exit0;
		}
		WriteConsole( hStdOut, pwstrValueNameBuffer, ulValueNameSize, &ulBytesWritten, NULL);
		
		switch(ulType)
		{
		case REG_DWORD:
			{
				printf(" Type: REG_DWORD");
				printf(" Value: %d", *(PULONG)pValueData);
			}
			break;
		case REG_SZ:
			{
				printf(" Type: REG_SZ");
				printf(" Value: ");
				WriteConsole( hStdOut, (PWCHAR)pValueData, ulValueDataLen / sizeof(WCHAR), &ulBytesWritten, NULL);
			}
			break;
		case REG_EXPAND_SZ:
			{
				printf(" Type: REG_EXPAND_SZ");
				printf(" Value: ");
				WriteConsole( hStdOut, (PWCHAR)pValueData, ulValueDataLen / sizeof(WCHAR), &ulBytesWritten, NULL);
			}
			break;
		default:
			break;
		}
		WriteConsole( hStdOut, L"\n", 1, &ulBytesWritten, NULL);
	}

	lResult = ERROR_SUCCESS;
Exit0:
	if (NULL != pValueData)
	{
		free(pValueData);
	}
	if (NULL != pwstrSubKeyNameBuffer)
	{
		free(pwstrSubKeyNameBuffer);
	}
	if (NULL != pwstrValueNameBuffer)
	{
		free(pwstrValueNameBuffer);
	}
	if (INVALID_HANDLE_VALUE != hKeyHandle)
	{
		NIAPHiveCloseKey(hHiveHandle, hKeyHandle);
	}
	if ((NULL != hHiveHandle) && (INVALID_HANDLE_VALUE != hFileMappingHandle) && (INVALID_HANDLE_VALUE != hFileHandle))
	{
		NIAPHiveCloseHive(hFileHandle, hFileMappingHandle, hHiveHandle);
	}
	return lResult;
}
//-----------------------------------------------------------------------------//
 


2008年05月11日


    摘要:

驱动拦截键盘输入 保护密码不被截获

拦截dll加载,对应用程序做保护

主要用于网游和im的密码输入保护

有意请联系 niapsoft@hotmail.com

    (全文共151字)——点击此处阅读全文


2007年06月30日


    摘要:

直到拿在手里.
当初选择不要那么容易的得到,现在看来我还是没有后悔当初的决定. 

对电影里的正面人物,英雄们没有负出代价最后来个圆满的结局,一直都怀疑.

 

    (全文共117字)——点击此处阅读全文


2007年05月13日


    摘要:

今天很高兴能和朋友们一起做事,只是这事我不会,帮不上忙,而朋友们又是来帮我的忙。一直鼓捣了一晚上。好像又回到了大二那时候,在网络中心一起讨论和做东西。马上毕业了,不知道还有多少这样的时候能和朋友们在一起。

当时突然有的感觉就是朋友们在一起就没有做不了的事。真希望将来我们这几个能在一起干些事情。

    (全文共162字)——点击此处阅读全文


2007年04月18日


    摘要:

http://www.rootkit.com/vault/uty/FileExposure.rar

因为董老大说程序要到产品化,所以想还是放出来,这样估计bug就出来不少了

    (全文共165字)——点击此处阅读全文


2007年04月12日


    摘要:

晚上出去的晚了点,9点半爸给我来电话,后来把电话交给了我妈,说了2句又是我爸接的,说刚做晚手术别让我妈多说话

接完电话往公司走的时候,这一刻我觉得很幸福

    (全文共91字)——点击此处阅读全文


2007年03月10日


    摘要:煮熟的米粒大    (全文共6字)——点击此处阅读全文


2006年12月18日


    摘要:    鼠标早就坏了,左键不能用,懒的跑出去买。再说就这么坏了就换就有点被鼠标打败了的感觉。最主要的原因还是懒人啥都能凑合。     windows下还好说,我用鼠标键+左右键调换还能凑合着用。这两天突然想学学linux,x下没左键是寸步难行,只好改改了。我鼠标还有滚轮,可以 当左键往下按。     linux下负责鼠标,键盘,及其它usb输入设备的被称做input subsystem。linux journAl上有两篇介绍的文章www.linuxjournal.com/article/6396     (全文共23348字)——点击此处阅读全文


2006年12月10日


    摘要:http://writeblog.donews.com/login.aspx?ReturnUrl=/editposts.aspx
在教育网里点登陆就不是这个地址,奇怪    (全文共88字)——点击此处阅读全文


2006年10月29日


    摘要:https://www.rootkit.com/newsread.php?newsid=591    (全文共1635字)——点击此处阅读全文




    摘要:很久没上blog了,教育网里也登不上. 几个月不见donews的blog成了这个鸟样,小广告也给贴上了,代码也都给我堆到一行上.....     (全文共80字)——点击此处阅读全文


2006年05月10日


    摘要:以前给朋友弄的,我也忘了怎么用了,在命令行下把注册表的项设成deny|Allow|reAdonly,改了后可以看SAM,也可以让run什么的变成只读的什么的 -____-     (全文共28726字)——点击此处阅读全文