精华内容
下载资源
问答
  • Windows中获取线程起始地址

    千次阅读 2016-05-13 21:56:36
    偶尔碰到了一个小需求,要验证一个线程起始于某个模块... 线程的起始地址StartAddress,保存在了 _ETHREAD 结构中,无法从Ring3获取。 kd> dt _ethread 80553740 ntdll!_ETHREAD +0x000 Tcb : _KTHREAD +0x1c0 Cre

            偶尔碰到了一个小需求,要验证一个线程起始于某个模块,可以限制对代码的执行,起始于特定的线程。

            线程的起始地址StartAddress,保存在了 _ETHREAD 结构中,无法从Ring3获取。

    kd> dt _ethread 80553740  
    ntdll!_ETHREAD
       +0x000 Tcb              : _KTHREAD
       +0x1c0 CreateTime       : _LARGE_INTEGER 0x0
       +0x1c0 NestedFaultCount : 0y00
       +0x1c0 ApcNeeded        : 0y0
       +0x1c8 ExitTime         : _LARGE_INTEGER 0x0
       +0x1c8 LpcReplyChain    : _LIST_ENTRY [ 0x0 - 0x0 ]
       +0x1c8 KeyedWaitChain   : _LIST_ENTRY [ 0x0 - 0x0 ]
       +0x1d0 ExitStatus       : 0
       +0x1d0 OfsChain         : (null) 
       +0x1d4 PostBlockList    : _LIST_ENTRY [ 0x0 - 0x0 ]
       +0x1dc TerminationPort  : (null) 
       +0x1dc ReaperLink       : (null) 
       +0x1dc KeyedWaitValue   : (null) 
       +0x1e0 ActiveTimerListLock : 0
       +0x1e4 ActiveTimerListHead : _LIST_ENTRY [ 0x0 - 0x0 ]
       +0x1ec Cid              : _CLIENT_ID
       +0x1f4 LpcReplySemaphore : _KSEMAPHORE
       +0x1f4 KeyedWaitSemaphore : _KSEMAPHORE
       +0x208 LpcReplyMessage  : (null) 
       +0x208 LpcWaitingOnPort : (null) 
       +0x20c ImpersonationInfo : (null) 
       +0x210 IrpList          : _LIST_ENTRY [ 0x0 - 0x0 ]
       +0x218 TopLevelIrp      : 0
       +0x21c DeviceToVerify   : (null) 
       +0x220 ThreadsProcess   : (null) 
       +0x224 StartAddress     : (null) 
       +0x228 Win32StartAddress : (null) 
       +0x22c  ......
       ......

            有一个Native的函数,可以获取到线程的其实地址。该Native函数是 NtQueryInformationThread,第二个参数设置为ThreadQuerySetWin32StartAddress,即可获取线程的起始地址。

    DWORD WINAPI GetThreadStartAddress(HANDLE hThread)
    {
    	NTSTATUS ntStatus;
    	HANDLE hDupHandle;
    	DWORD dwStartAddress;
    
    	pNtQIT NtQueryInformationThread = (pNtQIT)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationThread");
    	if(NtQueryInformationThread == NULL) return 0;
    
    	HANDLE hCurrentProcess = GetCurrentProcess();
    	if(!DuplicateHandle(hCurrentProcess, hThread, hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){
    		SetLastError(ERROR_ACCESS_DENIED);
    		return 0;
    	}
    	ntStatus = NtQueryInformationThread(hDupHandle, ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD), NULL);
    	CloseHandle(hDupHandle);
    
    	if(ntStatus != STATUS_SUCCESS) return 0;
    	return dwStartAddress;
    }



    展开全文
  • C++ 获取线程入口地址、所在模块

    千次阅读 2019-08-20 14:57:14
    今天检测的特征是向 YY语音 里插入了一段自己的代码(创建了新的线程),而这个新的线程不在原有的模块内,所以思路就是遍历 YY.exe 这个进程中的所有线程,如果这个线程没有对应的模块,那么就说明这个线程是可疑的...

    大多数恶意代码为了隐藏自己的行踪都会附加到某个进程中,在这个进程内申请一块内存区域来存放它的代码,毕竟隐藏的再好,代码也要有的,不然你让 CPU 运行什么 …
    在这里插入图片描述
    今天检测的特征是向 YY语音 里插入了一段自己的代码(创建了新的线程),而这个新的线程不在原有的模块内,所以思路就是遍历 YY.exe 这个进程中的所有线程,如果这个线程没有对应的模块,那么就说明这个线程是可疑的。

    准备工作:

    #pragma region 依赖
    typedef enum _THREADINFOCLASS{
        ThreadBasicInformation,
        ThreadTimes,
        ThreadPriority,
        ThreadBasePriority,
        ThreadAffinityMask,
        ThreadImpersonationToken,
        ThreadDescriptorTableEntry,
        ThreadEnableAlignmentFaultFixup,
        ThreadEventPair_Reusable,
        ThreadQuerySetWin32StartAddress,
        ThreadZeroTlsCell,
        ThreadPerformanceCount,
        ThreadAmILastThread,
        ThreadIdealProcessor,
        ThreadPriorityBoost,
        ThreadSetTlsArrayAddress,
        ThreadIsIoPending,
        ThreadHideFromDebugger,
        ThreadBreakOnTermination,
        MaxThreadInfoClass
    }THREADINFOCLASS;
    typedef struct _CLIENT_ID{
        HANDLE UniqueProcess;
        HANDLE UniqueThread;
    }CLIENT_ID;
    typedef struct _THREAD_BASIC_INFORMATION{
        LONG ExitStatus;
        PVOID TebBaseAddress;
        CLIENT_ID ClientId;
        LONG AffinityMask;
        LONG Priority;
        LONG BasePriority;
    }THREAD_BASIC_INFORMATION,*PTHREAD_BASIC_INFORMATION;
    extern "C" LONG (__stdcall *ZwQueryInformationThread)(
        IN HANDLE ThreadHandle,
        IN THREADINFOCLASS ThreadInformationClass,
        OUT PVOID ThreadInformation,
        IN ULONG ThreadInformationLength,
        OUT PULONG ReturnLength OPTIONAL
        ) = NULL;
    #pragma endregion
    
    

    功能实现:

    	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);	// 进程快照句柄
    	PROCESSENTRY32 process = {sizeof(PROCESSENTRY32)};						// 进程快照信息
    
    	// 遍历进程,找到 YY.exe
    	while (Process32Next(hProcessSnap,&process)){
    		string s_szExeFile = process.szExeFile; // char* 转 string
    		if(s_szExeFile == "YY.exe"){
    			HANDLE hThreadSnap = INVALID_HANDLE_VALUE;			// 线程快照句柄 
    			THREADENTRY32 te32;									// 线程快照信息
    
    			// 创建线程快照
    			hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    			if (hThreadSnap == INVALID_HANDLE_VALUE){cout << "创建线程快照失败" << endl;}
    
    			// 为快照分派内存空间
    			te32.dwSize = sizeof(THREADENTRY32);
    
    			// 获取第一个线程的信息
    			if (!Thread32First(hThreadSnap, &te32)){cout << "线程信息获取失败" << endl;}
    
    			// 遍历线程
    			while (Thread32Next(hThreadSnap, &te32)){
    				// 线程属于 YY.exe
    				if(te32.th32OwnerProcessID == process.th32ProcessID){
    					// 打开线程
    					HANDLE hThread = ::OpenThread (
    						THREAD_ALL_ACCESS,		// 访问权限,THREAD_ALL_ACCESS :所有权限
    						FALSE,					// 由此线程创建的进程不继承线程的句柄
    						te32.th32ThreadID		// 线程 ID
    						);
    					if(hThread == NULL){cout << "线程打开失败" << endl;}
    
    					// 将区域设置设置为从操作系统获取的ANSI代码页
    					setlocale(LC_ALL,".ACP");
    
    					// 获取 ntdll.dll 的模块句柄
    					HINSTANCE hNTDLL = ::GetModuleHandle("ntdll");	
    
    					// 从 ntdll.dll 中取出 ZwQueryInformationThread
    					(FARPROC&)ZwQueryInformationThread  = ::GetProcAddress(hNTDLL,"ZwQueryInformationThread");
    					
    					// 获取线程入口地址
    					PVOID startaddr;						// 用来接收线程入口地址
    					ZwQueryInformationThread(
    						hThread,							// 线程句柄
    						ThreadQuerySetWin32StartAddress,	// 线程信息类型,ThreadQuerySetWin32StartAddress :线程入口地址
    						&startaddr,							// 指向缓冲区的指针
    						sizeof(startaddr),					// 缓冲区的大小
    						NULL								
    						);
    
    					// 获取线程所在模块
    					THREAD_BASIC_INFORMATION tbi;			// _THREAD_BASIC_INFORMATION 结构体对象
    					TCHAR modname[MAX_PATH];				// 用来接收模块全路径
    					ZwQueryInformationThread(
    						hThread,							// 线程句柄
    						ThreadBasicInformation,				// 线程信息类型,ThreadBasicInformation :线程基本信息
    						&tbi,								// 指向缓冲区的指针
    						sizeof(tbi),						// 缓冲区的大小
    						NULL
    						);
    
    					// 检查入口地址是否位于某模块中
    					GetMappedFileName(
    						::OpenProcess(						// 进程句柄
    							PROCESS_ALL_ACCESS,									// 访问权限,THREAD_ALL_ACCESS :所有权限
    							FALSE,												// 由此线程创建的进程不继承线程的句柄
    							(DWORD)tbi.ClientId.UniqueProcess					// 唯一进程 ID
    							), 
    						startaddr,							// 要检查的地址
    						modname,							// 用来接收模块名的指针
    						MAX_PATH							// 缓冲区大小
    						);
    					
    					// 判断线程是否在模块中
    					if(modname[0] == '?'){cout << "线程不在模块中" << endl;}
    				}
    			}			
    		}
    	}
    

    另外感谢 gongwan33 老哥提供的思路
    在这里插入图片描述

    展开全文
  • linux获取线程ID

    千次阅读 2017-11-07 14:38:46
    原文地址:http://www.linuxidc.com/Linux/2014-01/94723.htm 最近一直在想: 如何确认两段代码是不是在同一个线程中执行的呢? 通过查看资料,发现一种比较简单的方法就是在代码中使用printf将当前线程的id...

    原文地址:http://www.linuxidc.com/Linux/2014-01/94723.htm

    最近一直在想:
    如何确认两段代码是不是在同一个线程中执行的呢?

    通过查看资料,发现一种比较简单的方法就是在代码中使用printf将当前线程的id打印出来。
    而这也分成两种情况:
    1. 如果是pthread,则使用,
    #include <pthread.h>

    pthread_t pthread_self(void);

    2. 如果不是pthread,即是由内核创建的线程,则使用,
    #include <sys/types.h>

    pid_t gettid(void);

    获取线程所在的进程的id,方法如下:
    #include <sys/types.h>
    #include <unistd.h>

    pid_t getpid(void);
    pid_t getppid(void);

    所以,我们在代码中使用如下的语句打印:
    printf("\ntid=%lu, pid=%lu\n", gettid(), getpid());
    这样就能获取当前代码所在的线程和进程了。

    根据打印出来的进程的pid,获取进程名的方法是:
    ls -lh /proc/pid/exe
    lrwxrwxrwx 1 root root 0 Jan  1 20:48 /proc/pid/exe -> ...
    sh-3.2#

    查看thread id的方法有:
    1. sh-3.2# ps -efL | grep process,
    ps命令指定-L命令选项可以用来查看进程下所包含的所有线程。

    2. sh-3.2# ls -l /proc/pid/task/
    查看进程下当前有哪些task,这些task指的就是线程。

    测试所遇到的实际状况:
    1. 运行后发现两个线程虽然是同属于一个进程,但是使用如上两种方法查看线程时只能看到其中一个线程。
    猜测是另一个线程已经退出了?有空时可以再确认一下。

    2. 调用gettid()会出现编译错误,其原因是gettid是一个系统调用,在glibc中没有对应的库函数。
    用户如果有需要,可以直接调用gettid所对应的系统调用。


    展开全文
  • python 中获取线程id

    万次阅读 2018-07-02 16:00:50
    1、python下使用ctypes获取threading线程idpython的多线程坑坑不断… …python的threading因为封装的太好, 很多本源的东西在threading对象里是拿不到的. 首先需要说明的是python threading的name跟ident,这些看起来...

    该问题的解决主要参考了网上的几篇文章,在此一并谢过。

    1、python下使用ctypes获取threading线程id

    python的多线程坑坑不断… …

    python的threading因为封装的太好, 很多本源的东西在threading对象里是拿不到的.  首先需要说明的是python threading的name跟ident,这些看起来是线程名字,线程id其实只是个标识,注意是标识而已.  简单过了下threading创建对象及启动线程的代码,发现ident跟pstree查到的线程id是两码事. 

    该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新http://xiaorui.cc/?p=3017

    我在 stackoverflow 查询到了一些关于pyhton线程id的获取方式,但大多数人其实对线程id是不关心的,他们会利用threading给予的threading.currentThread().ident threading.currentThread().name来识别线程.  最后在查到一老外写的使用ctypes调用系统的动态链接库libc.so.6 来获取线程id的方法, 当然事实证明是有效果的. 

    老外的连接 http://blog.devork.be/2010/09/finding-linux-thread-id-from-within.html

    ctypes是Python的一个外部库,提供和C语言兼容的数据类型,可以很方便地调用C DLL中的函数. 我对这个ctypes理解也不深入,在以前的项目中用过,表示有些粗暴.

    废话不多说, 直接上python ctypes样例,关于这186,224,178不知道啥意思.

    下面是python threading获取线程id的实例代码:

    这是上面py代码运行后的结果,  跟我们预期的效果一致.


    可以另起一个终端使用pstree -p pid看看是否正确.  


    那么我们费尽心思取到python的线程id是为了什么?  strace -p pid/线程 的状态.  可以看到24831线程正在建立google.com的连接, 很明显这连接被拒了.

    END.  下次有时间在专门瞅瞅python ctypes的用法. 

    对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!! 
    { 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 } 

    另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用. 
    如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!

    其中提到的老外的文章:

    So I've got a multi-threaded application and suddenly I notice there's one thread running away and using all CPU. Not good, probably a loop gone wrong. But where? One way to find this is revert history in the VCS and keep trying it out till you find the bad commit. Another way is to find out which thread is doing this, this is of course much more fun!

    Using ps -p PID -f -L you'll see the thread ID which is causing the problems. To relate this to a Python thread I subclass threading.Thread, override it's .start() method to first wrap the .run() method so that you can log the thread ID before calling the original .run(). Since I was already doing all of this apart from the logging of the thread ID this was less work then it sounds. But the hard part is finding the thread ID.

    Python knows of a threading.get_ident() method but this is merely a long unique integer and does not correspond to the actual thread ID of the OS. The kernel allows you to get the thread ID: getid(2). But this must be called using a system call with the constant name SYS_gettid. Because it's hard to use constants in ctypes (at least I don't know how to do this), and this is not portable anyway, I used this trivial C program to find out the constant value:

    #include <stdio.h>
    #include <sys/syscall.h>
    
    int main(void)
    {
        printf("%d\n", SYS_gettid);
        return 0;
    }
    

    In my case the constant to use is 186. Now all that is left is using ctypes to do the system call:

    import ctypes
    
    SYS_gettid = 186
    libc = ctypes.cdll.LoadLibrary('libc.so.6')
    tid = libc.syscall(SYS_gettid)
    

    That's it! Now you have the matching thread ID!

    Going back to the original problem you can now associate this thread ID with the thread name and you should be able to find the problematic thread.

    对于‘libc.so.6'的使用可以是直接调用或是先载入(Loadlibrary)都行。

    2、采用ubuntu系统时可能会碰到libc.so.6位置的问题,即无法导入模块,或无法找到该动态库时解决方法:

    在Ubuntu 14.04LTS用命令:/lib/libc.so.6时,提示” /lib/libc.so.6: not found“,其实这个库是存在的,只是地方换了,在"/lib/i386-linux-gnu/"下面,我们只需创建一个链接即可。


    使用下面的命令:


    For 64 bit:

    sudo ln -s /lib64/x86_64-linux-gnu/libc-2.13.so /lib64/libc.so.6


    For 32 bit:

    sudo ln -s /lib/i386-linux-gnu/libc-2.13.so /lib/libc.so.6


    http://xiaorui.cc/2016/03/21/python%E4%B8%8B%E4%BD%BF%E7%94%A8ctypes%E8%8E%B7%E5%8F%96threading%E7%BA%BF%E7%A8%8Bid/

    http://blog.51cto.com/happyliu/1731402

    展开全文
  • MFC 获取线程ID

    千次阅读 2014-05-15 15:10:07
    于是网上找各种获取线程ID的方法,把找到的几种写下来方便以后用   1.通过进程映射名称获取主线程ID(进程映射名应为全大写,如谷歌浏览器的进程名:CHROME.EXE)   DWORD WINAPI GetThreadIDByName...
  • Pthread编程-设置/获取线程属性

    千次阅读 2017-05-01 17:15:17
    Pthread编程-设置/获取线程属性文章介绍如何设置/获取线程属性。与线程属性相关的函数大都以 pthread_attr_*开头,pthread_attr_get*用于获取线程属性,pthread_attr_get*用于设置线程属性。 这里仅罗列一些比较...
  • linux syscall系统调用获取线程PID

    千次阅读 2015-09-05 17:40:42
    linux syscall系统调用获取线程PID线程idLinux中,每个进程有一个pid,类型pid_t,由getpid()取得。Linux下的POSIX线程也有一个id,类型 pthread_t,由pthread_self()取得,该id由线程库维护,其id空间是各个进程...
  • 1. WIN32 API线程的创建 在程序中调用CreateThread函数可以创建一个线程: [cpp] view plaincopy HANDLE CreateThread(   LPSECURITY_ATTRIBUTES lpThreadAttributes,   DWORD ...
  • Linux下获取线程ID的方法

    万次阅读 2014-12-06 19:39:16
    Linux下多线程程序发生coredump时,用 gdb /path/to/program/file core 可以看到所有线程 root@rubic:~/test/thread# gdb a.out core GNU ...from /lib/libc.so.6 (gdb) 向0x0000000c(保留地址)写数据导致sigsegv
  • 函数原型: #include int pthread_create(pthread_t*thread,pthread_attr_t *attr, void * (*start_routine)(void *arg), void *arg);   ... 第三个参数是线程运行函数的地址。  最后一个
  • 获取线程Id的方法

    千次阅读 2018-08-22 21:24:24
    这段代码返回了当前线程的descriptor,pthread_self()得到的就是这个descriptor的地址, 也就是unsigned long int类型的pthread_t。知道了这一点就好办了,找到thread descriptor的定义:  struct pthread  {  ....
  • 从线程ID获取线程名称通常的方法是,先获取该线程的入口地址,然后枚举进程内所有已加载模块,最后判断线程入口地址落在哪个加载模块范围内。枚举进程内已加载模块可用Win32标准的CreateToolhelp32Snapshot/Mo
  • 转载自:http://blog.csdn.net/jasonblog/article/details/49909163如果要获取当前线程的调用栈,可以直接使用现有API:[NSThread ...我的理解是应该包含当前线程的执行地址,并且从这个地址可以一级一...
  • Java如何获取当前线程

    万次阅读 2018-07-05 08:26:48
    Java 中经常会遇到要获取当前线程的情况,这时一般我们就会通过Thread.currentThread()来获取,接下去就看看执行该语句在 JVM 中做了什么吧。 简单例子 以下是一个简单的例子,获取当前线程并打印线程名称,输出...
  • 线程 NSThread 多线程 获取当前线程

    万次阅读 2014-02-21 18:55:19
    线程 NSThread 多线程 线程与进程 进程 是一个活动的程序,一个容器 是系统资源管理的最小单位 切换代价较高 线程 是在进程容器中运行,实际工作的代码 是程序执行的最小单位 切换代价较低(由于线程是在同一块内存...
  • 多半是有个线程在搞鬼,杀掉这个线程就可以正常附加调试了),首先要找到线程入口地址,在网上找了下,发现在获取64位程序的线程信息时,入口地址是错的(64位的地址溢出了),稍稍改动了一下(要编译为64位) ...
  • 线程池使用FutureTask的时候如果拒绝策略设置为了 DiscardPolicy和DiscardOldestPolicy并且在被拒绝的任务的Future对象上调用无参get方法那么调用线程会一直被阻塞。 问题复现 下面就通过一个简单的例子来复现问题...
  • 在linux中的多线程一节中,我们介绍了利用pthread_create()函数创建子线程的方法。这种方式创建的线程存在一个问题:在主线程创建完成子线程后,若子线程函数 还没结束时,但是此时主线程函数已经结束,那么子线程也...
  • linux获取线程Id的三种方法

    万次阅读 2011-05-03 14:50:00
    我使用了第二种方法,很方便: #define gettid() syscall(__NR_gettid) 用到的地方 gettid() 在linux2.4版本后,linux使用了NPTL作为自己的线程库,为了兼容POSIX标准,所以在内核task中有两个域tgid和tid,...
  • C# 获取线程ID

    千次阅读 2018-04-01 08:07:55
    【下载地址】: 自己搜索下载 【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教! 【详细过程】 采用线程池线程执行任务我们无法直接控制线程.有时我们想直接控制线程的行为,那么我们可以创建...
  • // 线程处于等待的原因的枚举常量 typedef   enum   _KWAIT_REASON {   Executive ,   FreePage ,   PageIn ,   PoolAllocation ,   DelayExecution , ...
  • Linux下多线程编程__线程的创建pthread_create与退出pthread_exit,等待当前线程退出pthread_join,获取线程ID pthread_self  2010-11-24 12:31:06| 分类: Linux高性能开发 |举报 |字号 订阅 ...
  • Java获取当前所有线程

    万次阅读 2018-05-08 23:15:14
    ThreadGroup group = Thread.currentThread().getThreadGroup(); ThreadGroup topGroup = group...// 遍历线程组树,获取线程组 while (group != null) { topGroup = group; group = group.getParent(); } ...
  • 关于线程栈与线程地址空间

    千次阅读 2018-04-11 09:30:23
    线程栈与地址空间Linux系统把所有线程都当做进程来实现,线程作为轻量级进程(LWP)。线程仅仅被视为一个与其他进程共享某些资源的进程,而是否共享地址空间几乎是进程和 Linux 中所谓线程的唯一区别。线程创建的...
  • 获取当前进程 / 线程的 ID 、句柄和内核地址 在用户态( RING3 )和内核态( RING0 )下,获取这些值的函数是不同的,而且这些函数的实现原理也是不同的,下面做个小结: 1. 用户态( RING3 )下 2. 内核...
  • MFC 多线程及线程同步

    千次阅读 2016-11-27 21:54:13
    一、MFC对多线程编程的支持  MFC中有两类线程,分别称之为工作者线程和用户界面线程。...用户界面线程一般用于处理独立于其他线程执行之外的用户输入,响应用户系统所产生的事件和消息等。但对于Win32的API

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 389,615
精华内容 155,846
关键字:

获取线程及地址