我用织梦5.7做个网站应该把淘宝客店铺链接放到哪,深圳网站建设找哪家公司好,如何给自己建设的网站设置登陆用户名和密码,四大门户网站创始人syscall的检测与绕过
ntdll中syscall被执行的格式大致 我们可以通过检测mov r10, rcx类似的代码来确定程序是否直接进行系统调用。
但是很容易被bypass 而且还可以写出很多不一样的写法#xff0c;显然这个方式是不行的。很轻易就会被bypass。
当然也可以检测syscall指令显然这个方式是不行的。很轻易就会被bypass。
当然也可以检测syscall指令但是这个指令可以同int 2e中断门进0环的方式绕过也可以加一个int 2e的规则。
objdump --disassemble -M intel D:\C Project\bypass\syscall\x64\Release\syscall.exe | findstr syscall syscall也可以不直接写写死在文件种比如先用垃圾指令写死在文件中然后在运行的时候对这些垃圾指令进行修改重新为syscall达到静态绕过的效果。
这也正是SysWhispers3为了规避检测做的升级之一称为EGG的手段。 可以像这样编写ntapi 这个w00tw00t就是一个垃圾指令我们将在执行的过程中重新替换为syscall 更改指令代码
#include stdio.h
#include stdlib.h
#include Windows.h
#include psapi.h#define DEBUG 0HMODULE GetMainModule(HANDLE);
BOOL GetMainModuleInformation(PULONG64, PULONG64);
void FindAndReplace(unsigned char[], unsigned char[]);HMODULE GetMainModule(HANDLE hProcess)
{HMODULE mainModule NULL;HMODULE* lphModule;LPBYTE lphModuleBytes;DWORD lpcbNeeded;// First call needed to know the space (bytes) required to store the modules handlesBOOL success EnumProcessModules(hProcess, NULL, 0, lpcbNeeded);// We already know that lpcbNeeded is always 0if (!success || lpcbNeeded 0){printf([-] Error enumerating process modules\n);// At this point, we already know we wont be able to dyncamically// place the syscall instruction, so we can exitexit(1);}// Once we got the number of bytes required to store all the handles for// the process modules, we can allocate space for themlphModuleBytes (LPBYTE)LocalAlloc(LPTR, lpcbNeeded);if (lphModuleBytes NULL){printf([-] Error allocating memory to store process modules handles\n);exit(1);}unsigned int moduleCount;moduleCount lpcbNeeded / sizeof(HMODULE);lphModule (HMODULE*)lphModuleBytes;success EnumProcessModules(hProcess, lphModule, lpcbNeeded, lpcbNeeded);if (!success){printf([-] Error enumerating process modules\n);exit(1);}// Finally storing the main modulemainModule lphModule[0];// Avoid memory leakLocalFree(lphModuleBytes);// Return main modulereturn mainModule;
}BOOL GetMainModuleInformation(PULONG64 startAddress, PULONG64 length)
{HANDLE hProcess GetCurrentProcess();HMODULE hModule GetMainModule(hProcess);MODULEINFO mi;GetModuleInformation(hProcess, hModule, mi, sizeof(mi));printf(Base Address: 0x%llu\n, (ULONG64)mi.lpBaseOfDll);printf(Image Size: %u\n, (ULONG)mi.SizeOfImage);printf(Entry Point: 0x%llu\n, (ULONG64)mi.EntryPoint);printf(\n);*startAddress (ULONG64)mi.lpBaseOfDll;*length (ULONG64)mi.SizeOfImage;DWORD oldProtect;VirtualProtect(mi.lpBaseOfDll, mi.SizeOfImage, PAGE_EXECUTE_READWRITE, oldProtect);return 0;
}void FindAndReplace(unsigned char egg[], unsigned char replace[])
{ULONG64 startAddress 0;ULONG64 size 0;GetMainModuleInformation(startAddress, size);if (size 0) {printf([-] Error detecting main module size);exit(1);}ULONG64 currentOffset 0;unsigned char* current (unsigned char*)malloc(8*sizeof(unsigned char*));size_t nBytesRead;printf(Starting search from: 0x%llu\n, (ULONG64)startAddress currentOffset);while (currentOffset size - 8){currentOffset;LPVOID currentAddress (LPVOID)(startAddress currentOffset);if(DEBUG 0){printf(Searching at 0x%llu\n, (ULONG64)currentAddress);}if (!ReadProcessMemory((HANDLE)((int)-1), currentAddress, current, 8, nBytesRead)) {printf([-] Error reading from memory\n);exit(1);}if (nBytesRead ! 8) {printf([-] Error reading from memory\n);continue;}if(DEBUG 0){for (int i 0; i nBytesRead; i){printf(%02x , current[i]);}printf(\n);}if (memcmp(egg, current, 8) 0){printf(Found at %llu\n, (ULONG64)currentAddress);WriteProcessMemory((HANDLE)((int)-1), currentAddress, replace, 8, nBytesRead);}}printf(Ended search at: 0x%llu\n, (ULONG64)startAddress currentOffset);free(current);
}在inceptor中可以直接调用函数达到替换syscall的作用
int main(int argc, char** argv) {unsigned char egg[] { 0x77, 0x00, 0x00, 0x74, 0x77, 0x00, 0x00, 0x74 }; // w00tw00tunsigned char replace[] { 0x0f, 0x05, 0x90, 0x90, 0xC3, 0x90, 0xCC, 0xCC }; // syscall; nop; nop; ret; nop; int3; int3//####SELF_TAMPERING####(egg, replace);Inject();return 0;
}
但是这样依然很容易被检测原因是有了更加准确的检测方式。
那就是通过栈回溯。
当你正常的程序使用系统调用的时候。 此时你的流程是主程序模块-kernel32.dll-ntdll.dll-syscall这样当0环执行结束返回3环的时候这个返回地址应该是在ntdll所在的地址范围之内。
那么如果是你自己直接进行系统调用。 此时当ring0返回的时候rip将会是你的主程序模块内而并不是在ntdll所在的范围内这点是很容易被检测也是比较准确的一种检测方式。