sub

Popen.communicate(input=None)¶
Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optional input argument should be a string to be sent to the child process, or None, if no data should be sent to the child.

communicate() returns a tuple (stdoutdata, stderrdata).

Note that if you want to send data to the process’s stdin, you need to create the Popen object with stdin=PIPE. Similarly, to get anything other than None in the result tuple, you need to give stdout=PIPE and/or stderr=PIPE too.

Note The data read is buffered in memory, so do not use this method if the data size is large or unlimited.
我们可以在Popen()建立子进程的时候改变标准输入、标准输出和标准错误,并可以利用subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe):

import subprocess
child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["wc"], stdin=child1.stdout,stdout=subprocess.PIPE)
out = child2.communicate()
print(out)
subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。

要注意的是,communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。

 

我们还可以利用communicate()方法来使用PIPE给子进程输入:

import subprocess
child = subprocess.Popen(["cat"], stdin=subprocess.PIPE)
child.communicate("vamei")
我们启动子进程之后,cat会等待输入,直到我们用communicate()输入"vamei"。

 http://www.aikaiyuan.com/4705.html

https://buluo.qq.com/p/detail.html?bid=234299&pid=3596725-1483410241&from=share_copylink

转载于:https://www.cnblogs.com/newpython/p/6246524.html

// bad sp value at call has been detected, the output may be wrong! int __cdecl main(int argc, const char **argv, const char **envp) { _DWORD *_main_v3; // eax _DWORD *_main_v4; // eax int _main_v5; // eax struct Concurrency::details::stl_condition_variable_win7 *cv@_Cnd_internal_imp_t@@QAEPAVstl_condition_variable_win7@detai_2; // eax _DWORD *_main_v8; // esi _DWORD *_main_v9; // eax int _main_v10; // eax void *_main_v11; // eax int _main_v12; // eax int _main_v13; // [esp-8h] [ebp-1F4h] struct Concurrency::details::stl_condition_variable_win7 *cv@_Cnd_internal_imp_t@@QAEPAVstl_condition_variable_win7@detai; // [esp-4h] [ebp-1F0h] struct Concurrency::details::stl_condition_variable_win7 *cv@_Cnd_internal_imp_t@@QAEPAVstl_condition_variable_win7@detai_1; // [esp-4h] [ebp-1F0h] _DWORD _main_v16[10]; // [esp+0h] [ebp-1ECh] BYREF _DWORD _main_v17[24]; // [esp+28h] [ebp-1C4h] BYREF _BYTE _main_v18[4]; // [esp+88h] [ebp-164h] BYREF _DWORD _main_v19[24]; // [esp+8Ch] [ebp-160h] BYREF _BYTE _main_v20[4]; // [esp+ECh] [ebp-100h] BYREF int _main_v21; // [esp+F0h] [ebp-FCh] int _main_v22; // [esp+F8h] [ebp-F4h] int _main_v23; // [esp+FCh] [ebp-F0h] int _main_v24; // [esp+100h] [ebp-ECh] char _main_v25; // [esp+104h] [ebp-E8h] BYREF char _main_v26; // [esp+105h] [ebp-E7h] BYREF char _main_v27; // [esp+106h] [ebp-E6h] BYREF _BYTE _main_v29[24]; // [esp+108h] [ebp-E4h] BYREF _BYTE _main_v30[24]; // [esp+120h] [ebp-CCh] BYREF _BYTE _main_v31[24]; // [esp+138h] [ebp-B4h] BYREF _BYTE _main_v32[24]; // [esp+150h] [ebp-9Ch] BYREF _BYTE _main_v33[24]; // [esp+168h] [ebp-84h] BYREF _BYTE _main_v34[24]; // [esp+180h] [ebp-6Ch] BYREF _BYTE _main_v35[12]; // [esp+198h] [ebp-54h] BYREF _BYTE _main_v36[12]; // [esp+1A4h] [ebp-48h] BYREF _BYTE _main_v37[12]; // [esp+1B0h] [ebp-3Ch] BYREF _BYTE _main_v38[12]; // [esp+1BCh] [ebp-30h] BYREF _DWORD _main_v39[6]; // [esp+1C8h] [ebp-24h] BYREF int n5; // [esp+1E8h] [ebp-4h] _main_v39[5] = _main_v16; /* Inline expansion of sub_4029B0 */ void *__thiscall sub_4029B0(void *this) { unsigned __int8 sub_4029B0_v3; // [esp+7h] [ebp-1h] /* Inline expansion of sub_403FB0 */ _Cnd_internal_imp_t *__thiscall sub_403FB0(_Cnd_internal_imp_t *this, int a2) { _Cnd_internal_imp_t::_get_cv(this); /* Inline expansion of sub_4046E0 */ _DWORD *__thiscall sub_4046E0(_DWORD *this) { /* Inline expansion of unknown_libname_18 */ /* [Max depth reached at unknown_libname_18] */ /* End inline unknown_libname_18 */ this[4] = 0; this[5] = 0; return this; } /* End inline sub_4046E0 */ return this; } /* End inline sub_403FB0 */ /* Inline expansion of unknown_libname_3 */ // Microsoft VisualC 14/net runtime void __stdcall unknown_libname_3(int a1) { ; } /* End inline unknown_libname_3 */ /* Inline expansion of sub_402D60 */ int __thiscall sub_402D60(_DWORD *this) { char sub_402D60_v2; // [esp+Bh] [ebp-1h] BYREF this[4] = 0; this[5] = 15; sub_402D60_v2 = 0; return unknown_libname_14(this, &sub_402D60_v2); } /* End inline sub_402D60 */ return this; } /* End inline sub_4029B0 */ n5 = 0; /* Inline expansion of memset_w */ void *__thiscall sub_402390(void *this, size_t Size) { return memset(this, 0, Size); } /* End inline memset_w */ _main_v19[0] = 104; _main_v19[1] = 84; _main_v19[2] = 153; _main_v19[3] = 98; _main_v19[4] = 66; _main_v19[5] = 2; _main_v19[6] = 232; _main_v19[7] = 140; _main_v19[8] = 178; _main_v19[9] = 151; _main_v19[10] = 10; _main_v19[11] = 173; _main_v19[12] = 154; _main_v19[13] = 51; _main_v19[14] = 86; _main_v19[15] = 18; _main_v19[16] = 79; _main_v19[17] = 66; _main_v19[18] = 197; _main_v19[19] = 202; _main_v19[20] = 63; _main_v19[21] = 184; _main_v19[22] = 60; _main_v19[23] = 146; cv@_Cnd_internal_imp_t@@QAEPAVstl_condition_variable_win7@detai = _Cnd_internal_imp_t::_get_cv((_Cnd_internal_imp_t *)&_main_v27); _main_v3 = (_DWORD *)unknown_libname_4(_main_v19, _main_v20); /* Inline expansion of sub_402450 */ const struct std::_Container_base0 *__thiscall sub_402450( const struct std::_Container_base0 *this, char a2, int a3, struct Concurrency::details::stl_condition_variable_win7 *cv@_Cnd_internal_imp_t@@QAEPAVstl_condition_variable_win7@detai) { int sub_402450_v4; // eax int sub_402450_v6; // [esp-8h] [ebp-1Ch] unsigned __int8 sub_402450_v7; // [esp+6h] [ebp-Eh] unsigned __int8 sub_402450_v8; // [esp+7h] [ebp-Dh] char sub_402450_v10; // [esp+Fh] [ebp-5h] BYREF /* Inline expansion of sub_403C90 */ void *__thiscall sub_403C90( void *this, int a2, struct Concurrency::details::stl_condition_variable_win7 *cv@_Cnd_internal_imp_t@@QAEPAVstl_condition_variable_win7@detai) { /* Inline expansion of unknown_libname_9 */ // Microsoft VisualC 14/net runtime int __cdecl unknown_libname_9(int a1) { return a1; } /* End inline unknown_libname_9 */ /* Inline expansion of sub_404610 */ _DWORD *__thiscall sub_404610(_DWORD *this) { *this = 0; this[1] = 0; this[2] = 0; return this; } /* End inline sub_404610 */ return this; } /* End inline sub_403C90 */ std::_Fake_proxy_ptr_impl::_Fake_proxy_ptr_impl( (std::_Fake_proxy_ptr_impl *)&sub_402450_v10, (const struct std::_Fake_allocator *)&unk_40725D, this); sub_402450_v6 = unknown_libname_6(&a2); sub_402450_v4 = unknown_libname_7(&a2); /* Inline expansion of sub_403CC0 */ int __thiscall sub_403CC0(_DWORD *this, int a2, int a3, int a4) { int sub_403CC0_v4; // eax int sub_403CC0_result; // eax _DWORD *sub_403CC0_v7; // [esp+10h] [ebp-14h] BYREF int sub_403CC0_v8; // [esp+20h] [ebp-4h] sub_403CC0_v4 = sub_404DE0(a2, a3); sub_403CC0_result = unknown_libname_9(sub_403CC0_v4); if ( sub_403CC0_result ) { /* Inline expansion of sub_404640 */ int __thiscall sub_404640(void *this, unsigned int a2) { if ( a2 > std::_Tree<std::_Tmap_traits<void *,`anonymous namespace'::_Mutex_count_pair,std::less<void *>,std::_Crt_allocator<std::pair<void * const,`anonymous namespace'::_Mutex_count_pair>>,0>>::max_size(this) ) /* Inline expansion of sub_404810 */ /* [Max depth reached at sub_404810] */ /* End inline sub_404810 */ return sub_404820(a2); } /* End inline sub_404640 */ sub_403CC0_v7 = this; sub_403CC0_v8 = 0; this[1] = sub_404DF0(a2, a3, *this); sub_403CC0_v7 = 0; sub_403CC0_v8 = -1; return sub_404420(&sub_403CC0_v7); } return sub_403CC0_result; } /* End inline sub_403CC0 */ /* Inline expansion of unknown_libname_2 */ // Microsoft VisualC 14/net runtime void unknown_libname_2() { ; } /* End inline unknown_libname_2 */ return this; } /* End inline sub_402450 */ LOBYTE(n5) = 1; /* Inline expansion of memset_w */ /* [Skipped recursive call to memset_w] */ /* End inline memset_w */ _main_v17[0] = 18; _main_v17[1] = 26; _main_v17[2] = 125; _main_v17[3] = 6; _main_v17[4] = 7; _main_v17[5] = 111; _main_v17[6] = 76; _main_v17[7] = 104; _main_v17[8] = 122; _main_v17[9] = 4; _main_v17[10] = 124; _main_v17[11] = 13; _main_v17[12] = 93; _main_v17[13] = 112; _main_v17[14] = 103; _main_v17[15] = 9; _main_v17[16] = 97; _main_v17[17] = 112; _main_v17[18] = 111; _main_v17[19] = 93; _main_v17[20] = 105; _main_v17[21] = 99; _main_v17[22] = 79; _main_v17[23] = 10; cv@_Cnd_internal_imp_t@@QAEPAVstl_condition_variable_win7@detai_1 = _Cnd_internal_imp_t::_get_cv((_Cnd_internal_imp_t *)&_main_v26); _main_v4 = (_DWORD *)unknown_libname_4(_main_v17, _main_v18); /* Inline expansion of sub_402450 */ /* [Skipped recursive call to sub_402450] */ /* End inline sub_402450 */ LOBYTE(n5) = 2; /* Inline expansion of sub_402870 */ _Cnd_internal_imp_t *__thiscall sub_402870(_Cnd_internal_imp_t *this, void *Src) { unsigned __int8 sub_402870_v3; // [esp+Bh] [ebp-19h] char sub_402870_v5; // [esp+13h] [ebp-11h] BYREF int sub_402870_v6; // [esp+20h] [ebp-4h] /* Inline expansion of sub_403FB0 */ /* [Skipped recursive call to sub_403FB0] */ /* End inline sub_403FB0 */ sub_402870_v6 = 0; std::_Fake_proxy_ptr_impl::_Fake_proxy_ptr_impl( (std::_Fake_proxy_ptr_impl *)&sub_402870_v5, (const struct std::_Fake_allocator *)&unk_40725D, this); /* Inline expansion of sub_402D60 */ /* [Skipped recursive call to sub_402D60] */ /* End inline sub_402D60 */ std::string::assign(Src); /* Inline expansion of unknown_libname_2 */ /* [Skipped recursive call to unknown_libname_2] */ /* End inline unknown_libname_2 */ return this; } /* End inline sub_402870 */ LOBYTE(n5) = 3; /* Inline expansion of sub_4038F0 */ int __cdecl sub_4038F0(int a1, int a2) { __int64 sub_4038F0_v2; // rax _DWORD sub_4038F0_v4[4]; // [esp+0h] [ebp-90h] BYREF __int64 sub_4038F0_v5; // [esp+10h] [ebp-80h] __int64 sub_4038F0_v6; // [esp+18h] [ebp-78h] __int64 sub_4038F0_v7; // [esp+20h] [ebp-70h] int sub_4038F0_v8; // [esp+28h] [ebp-68h] int sub_4038F0_v9; // [esp+2Ch] [ebp-64h] BYREF int sub_4038F0_v10; // [esp+30h] [ebp-60h] BYREF int sub_4038F0_v11; // [esp+34h] [ebp-5Ch] int sub_4038F0_v12; // [esp+38h] [ebp-58h] int sub_4038F0_v13; // [esp+3Ch] [ebp-54h] int sub_4038F0_v14; // [esp+40h] [ebp-50h] BYREF int sub_4038F0_v15; // [esp+44h] [ebp-4Ch] BYREF int sub_4038F0_v16; // [esp+48h] [ebp-48h] int sub_4038F0_v17; // [esp+4Ch] [ebp-44h] int sub_4038F0_v18; // [esp+50h] [ebp-40h] __int64 sub_4038F0_v19; // [esp+54h] [ebp-3Ch] __int64 sub_4038F0_v20; // [esp+5Ch] [ebp-34h] __int64 sub_4038F0_v21; // [esp+64h] [ebp-2Ch] unsigned __int8 sub_4038F0_v22; // [esp+6Eh] [ebp-22h] unsigned __int8 sub_4038F0_v23; // [esp+6Fh] [ebp-21h] int sub_4038F0_v24; // [esp+70h] [ebp-20h] _BYTE sub_4038F0_v25[8]; // [esp+74h] [ebp-1Ch] BYREF _DWORD *sub_4038F0_v26; // [esp+80h] [ebp-10h] int sub_4038F0_v27; // [esp+8Ch] [ebp-4h] sub_4038F0_v26 = sub_4038F0_v4; sub_4038F0_v24 = 0; sub_4038F0_v20 = (unsigned int)unknown_libname_11(a2); sub_4038F0_v7 = std::ios_base::width((std::ios_base *)(*(_DWORD *)(*(_DWORD *)a1 + 4) + a1)); if ( sub_4038F0_v7 <= 0 || (sub_4038F0_v6 = std::ios_base::width((std::ios_base *)(*(_DWORD *)(*(_DWORD *)a1 + 4) + a1)), sub_4038F0_v6 <= sub_4038F0_v20) ) { sub_4038F0_v19 = 0; } else { sub_4038F0_v2 = std::ios_base::width((std::ios_base *)(*(_DWORD *)(*(_DWORD *)a1 + 4) + a1)); sub_4038F0_v19 = sub_4038F0_v2 - sub_4038F0_v20; } sub_4038F0_v21 = sub_4038F0_v19; /* Inline expansion of sub_4044E0 */ _BYTE *__thiscall sub_4044E0(_BYTE *this, int a2) { int sub_4044E0_v3; // [esp+4h] [ebp-14h] /* Inline expansion of sub_404780 */ void *__thiscall sub_404780(void *this, int a2) { int sub_404780_v4; // [esp+8h] [ebp-4h] *(_DWORD *)this = a2; sub_404780_v4 = std::ios::rdbuf(*(_DWORD *)(**(_DWORD **)this + 4) + *(_DWORD *)this); if ( sub_404780_v4 ) (*(void (__thiscall **)(int))(*(_DWORD *)sub_404780_v4 + 4))(sub_404780_v4); return this; } /* End inline sub_404780 */ if ( std::ios_base::good((std::ios_base *)(*(_DWORD *)(*(_DWORD *)a2 + 4) + a2)) ) { sub_4044E0_v3 = std::ios::tie(*(_DWORD *)(*(_DWORD *)a2 + 4) + a2); if ( sub_4044E0_v3 && sub_4044E0_v3 != a2 ) { std::ostream::flush(sub_4044E0_v3); this[4] = std::ios_base::good((std::ios_base *)(*(_DWORD *)(*(_DWORD *)a2 + 4) + a2)); } else { this[4] = 1; } } else { this[4] = 0; } return this; } /* End inline sub_4044E0 */ sub_4038F0_v27 = 0; if ( (unsigned __int8)unknown_libname_17(sub_4038F0_v25) ) { LOBYTE(sub_4038F0_v27) = 1; sub_4038F0_v18 = std::ios_base::flags((std::ios_base *)(*(_DWORD *)(*(_DWORD *)a1 + 4) + a1)); if ( (sub_4038F0_v18 & 0x1C0) != 0x40 ) { while ( sub_4038F0_v21 > 0 ) { sub_4038F0_v23 = std::ios::fill(*(_DWORD *)(*(_DWORD *)a1 + 4) + a1); sub_4038F0_v17 = std::ios::rdbuf(*(_DWORD *)(*(_DWORD *)a1 + 4) + a1); sub_4038F0_v16 = std::streambuf::sputc(sub_4038F0_v17, sub_4038F0_v23); sub_4038F0_v15 = sub_4038F0_v16; sub_4038F0_v14 = std::numeric_limits<unsigned int>::max(); if ( (unsigned __int8)unknown_libname_10(&sub_4038F0_v14, &sub_4038F0_v15) ) { sub_4038F0_v24 |= 4u; break; } --sub_4038F0_v21; } } if ( !sub_4038F0_v24 ) { sub_4038F0_v13 = std::ios::rdbuf(*(_DWORD *)(*(_DWORD *)a1 + 4) + a1); sub_4038F0_v5 = std::streambuf::sputn(sub_4038F0_v13, a2, sub_4038F0_v20, HIDWORD(sub_4038F0_v20)); if ( sub_4038F0_v5 != sub_4038F0_v20 ) sub_4038F0_v24 |= 4u; } if ( !sub_4038F0_v24 ) { while ( sub_4038F0_v21 > 0 ) { sub_4038F0_v22 = std::ios::fill(*(_DWORD *)(*(_DWORD *)a1 + 4) + a1); sub_4038F0_v12 = std::ios::rdbuf(*(_DWORD *)(*(_DWORD *)a1 + 4) + a1); sub_4038F0_v11 = std::streambuf::sputc(sub_4038F0_v12, sub_4038F0_v22); sub_4038F0_v10 = sub_4038F0_v11; sub_4038F0_v9 = std::numeric_limits<unsigned int>::max(); if ( (unsigned __int8)unknown_libname_10(&sub_4038F0_v9, &sub_4038F0_v10) ) { sub_4038F0_v24 |= 4u; break; } --sub_4038F0_v21; } } std::ios_base::width((std::ios_base *)(*(_DWORD *)(*(_DWORD *)a1 + 4) + a1), 0); sub_4038F0_v27 = 0; } else { sub_4038F0_v24 |= 4u; } std::ios::setstate(*(_DWORD *)(*(_DWORD *)a1 + 4) + a1, sub_4038F0_v24, 0); sub_4038F0_v8 = a1; sub_4038F0_v27 = -1; /* Inline expansion of sub_404460 */ int __thiscall sub_404460(_DWORD *this) { if ( !std::uncaught_exception() ) std::ostream::_Osfx(*this); return sub_404710(this); } /* End inline sub_404460 */ return sub_4038F0_v8; } /* End inline sub_4038F0 */ /* Inline expansion of sub_403C30 */ int __cdecl sub_403C30(int ?cin@std@@3V?$basic_istream@DU?$char_traits@D@std@@@1@A, _BYTE *a2) { int sub_403C30_v2; // eax sub_403C30_v2 = unknown_libname_9(?cin@std@@3V?$basic_istream@DU?$char_traits@D@std@@@1@A); return sub_4049A0(sub_403C30_v2, a2); } /* End inline sub_403C30 */ if ( unknown_libname_5(_main_v34) == 24 ) { /* [Library call preserved: memset] */ memset(_main_v39, 0, 16); /* Inline expansion of memset_w */ /* [Skipped recursive call to memset_w] */ /* End inline memset_w */ cv@_Cnd_internal_imp_t@@QAEPAVstl_condition_variable_win7@detai_2 = _Cnd_internal_imp_t::_get_cv((_Cnd_internal_imp_t *)&_main_v25); /* Inline expansion of sub_402650 */ void *__thiscall sub_402650( void *this, int n6, struct Concurrency::details::stl_condition_variable_win7 *cv@_Cnd_internal_imp_t@@QAEPAVstl_condition_variable_win7@detai) { _BYTE sub_402650_v5[2]; // [esp+6h] [ebp-2h] BYREF /* Inline expansion of sub_403C90 */ /* [Skipped recursive call to sub_403C90] */ /* End inline sub_403C90 */ /* Inline expansion of sub_403E70 */ void __thiscall sub_403E70(const struct std::_Container_base0 *this, unsigned int n6, _BYTE *a3) { const struct std::_Container_base0 *sub_403E70_v5; // [esp+10h] [ebp-18h] BYREF char sub_403E70_v6; // [esp+17h] [ebp-11h] BYREF int sub_403E70_v7; // [esp+24h] [ebp-4h] std::_Fake_proxy_ptr_impl::_Fake_proxy_ptr_impl( (std::_Fake_proxy_ptr_impl *)&sub_403E70_v6, (const struct std::_Fake_allocator *)&unk_40725D, this); if ( n6 ) { /* Inline expansion of sub_404640 */ /* [Skipped recursive call to sub_404640] */ /* End inline sub_404640 */ sub_403E70_v5 = this; sub_403E70_v7 = 0; *((_DWORD *)this + 1) = sub_404680(*(_DWORD *)this, n6, (unsigned __int8)*a3); sub_403E70_v5 = 0; sub_403E70_v7 = -1; /* Inline expansion of sub_404420 */ _DWORD *__thiscall sub_404420(_DWORD *this) { _DWORD *sub_404420_result; // eax sub_404420_result = this; if ( *this ) return (_DWORD *)sub_402B30(this); return sub_404420_result; } /* End inline sub_404420 */ } /* Inline expansion of unknown_libname_2 */ /* [Skipped recursive call to unknown_libname_2] */ /* End inline unknown_libname_2 */ } /* End inline sub_403E70 */ return this; } /* End inline sub_402650 */ LOBYTE(n5) = 4; _main_v8 = (_DWORD *)sub_402610(_main_v38); _main_v9 = (_DWORD *)sub_4026E0(_main_v34); *_main_v8 = *_main_v9; _main_v8[1] = _main_v9[1]; _main_v8[2] = _main_v9[2]; _main_v8[3] = _main_v9[3]; _main_v8[4] = _main_v9[4]; _main_v8[5] = _main_v9[5]; _main_v13 = sub_402400(_main_v38); _main_v10 = sub_402610(_main_v38); /* Inline expansion of sub_401600 */ int __cdecl sub_401600(int *a1, int a2, int a3) { int sub_401600_v3; // ecx int sub_401600_v4; // eax int sub_401600_v5; // edx int sub_401600_result; // eax int sub_401600_v7; // ecx int sub_401600_v8; // edx int sub_401600_v9; // [esp+18h] [ebp-18h] int sub_401600_v10; // [esp+18h] [ebp-18h] int sub_401600_v11; // [esp+1Ch] [ebp-14h] unsigned int sub_401600_v12; // [esp+20h] [ebp-10h] unsigned int sub_401600_v13; // [esp+20h] [ebp-10h] unsigned int sub_401600_v14; // [esp+24h] [ebp-Ch] unsigned int sub_401600_v15; // [esp+28h] [ebp-8h] unsigned int j; // [esp+2Ch] [ebp-4h] int i; // [esp+2Ch] [ebp-4h] int sub_401600_v18; // [esp+3Ch] [ebp+Ch] if ( a2 <= 1 ) { if ( a2 < -1 ) { sub_401600_v18 = -a2; sub_401600_v13 = -1640531527 * (52 / sub_401600_v18 + 6); sub_401600_v14 = *a1; do { sub_401600_v10 = (sub_401600_v13 >> 2) & 3; for ( i = sub_401600_v18 - 1; i; --i ) { sub_401600_v7 = a1[i] - (((a1[i - 1] ^ *(_DWORD *)(a3 + 4 * (sub_401600_v10 ^ i & 3))) + (sub_401600_v14 ^ sub_401600_v13)) ^ (((16 * a1[i - 1]) ^ (sub_401600_v14 >> 3)) + ((4 * sub_401600_v14) ^ ((unsigned int)a1[i - 1] >> 5)))); a1[i] = sub_401600_v7; sub_401600_v14 = sub_401600_v7; } sub_401600_v8 = *a1 - (((a1[sub_401600_v18 - 1] ^ *(_DWORD *)(a3 + 4 * sub_401600_v10)) + (sub_401600_v14 ^ sub_401600_v13)) ^ (((16 * a1[sub_401600_v18 - 1]) ^ (sub_401600_v14 >> 3)) + ((4 * sub_401600_v14) ^ ((unsigned int)a1[sub_401600_v18 - 1] >> 5)))); *a1 = sub_401600_v8; sub_401600_result = sub_401600_v8; sub_401600_v14 = sub_401600_v8; sub_401600_v13 += 1640531527; } while ( sub_401600_v13 ); } } else { sub_401600_v11 = 52 / a2 + 6; sub_401600_v12 = 0; sub_401600_v15 = a1[a2 - 1]; do { sub_401600_v12 -= 1640531527; sub_401600_v9 = (sub_401600_v12 >> 2) & 3; for ( j = 0; j < a2 - 1; ++j ) { sub_401600_v3 = ((sub_401600_v15 ^ *(_DWORD *)(a3 + 4 * (sub_401600_v9 ^ j & 3))) + (a1[j + 1] ^ sub_401600_v12)) ^ (((16 * sub_401600_v15) ^ ((unsigned int)a1[j + 1] >> 3)) + ((4 * a1[j + 1]) ^ (sub_401600_v15 >> 5))); sub_401600_v4 = a1[j]; a1[j] = sub_401600_v3 + sub_401600_v4; sub_401600_v15 = sub_401600_v3 + sub_401600_v4; } sub_401600_v5 = (((sub_401600_v15 ^ *(_DWORD *)(a3 + 4 * (sub_401600_v9 ^ j & 3))) + (*a1 ^ sub_401600_v12)) ^ (((16 * sub_401600_v15) ^ ((unsigned int)*a1 >> 3)) + ((4 * *a1) ^ (sub_401600_v15 >> 5)))) + a1[a2 - 1]; a1[a2 - 1] = sub_401600_v5; sub_401600_result = sub_401600_v5; sub_401600_v15 = sub_401600_v5; --sub_401600_v11; } while ( sub_401600_v11 ); } return sub_401600_result; } /* End inline sub_401600 */ _main_v11 = (void *)sub_402610(_main_v38); /* Inline expansion of sub_402910 */ _Cnd_internal_imp_t *__thiscall sub_402910(_Cnd_internal_imp_t *this, void *Src, size_t Size) { unsigned __int8 sub_402910_v4; // [esp+Bh] [ebp-19h] char sub_402910_v6; // [esp+13h] [ebp-11h] BYREF int sub_402910_v7; // [esp+20h] [ebp-4h] /* Inline expansion of sub_403FB0 */ /* [Skipped recursive call to sub_403FB0] */ /* End inline sub_403FB0 */ sub_402910_v7 = 0; std::_Fake_proxy_ptr_impl::_Fake_proxy_ptr_impl( (std::_Fake_proxy_ptr_impl *)&sub_402910_v6, (const struct std::_Fake_allocator *)&unk_40725D, this); /* Inline expansion of sub_402D60 */ /* [Skipped recursive call to sub_402D60] */ /* End inline sub_402D60 */ std::string::assign(Src, Size); /* Inline expansion of unknown_libname_2 */ /* [Skipped recursive call to unknown_libname_2] */ /* End inline unknown_libname_2 */ return this; } /* End inline sub_402910 */ LOBYTE(n5) = 5; /* Inline expansion of sub_401BA0 */ int __cdecl sub_401BA0(int a1, int a2) { _BYTE sub_401BA0_v3[24]; // [esp+4h] [ebp-7Ch] BYREF int sub_401BA0_v4[7]; // [esp+1Ch] [ebp-64h] BYREF int sub_401BA0_v5; // [esp+38h] [ebp-48h] int sub_401BA0_v6; // [esp+3Ch] [ebp-44h] int sub_401BA0_v7; // [esp+40h] [ebp-40h] int sub_401BA0_v8; // [esp+44h] [ebp-3Ch] int sub_401BA0_v9; // [esp+48h] [ebp-38h] int sub_401BA0_v10; // [esp+4Ch] [ebp-34h] unsigned __int8 *sub_401BA0_v11; // [esp+50h] [ebp-30h] unsigned __int8 sub_401BA0_v12; // [esp+57h] [ebp-29h] _BYTE sub_401BA0_v13[24]; // [esp+58h] [ebp-28h] BYREF int sub_401BA0_v14; // [esp+7Ch] [ebp-4h] sub_401BA0_v9 = 0; /* Inline expansion of sub_4029B0 */ /* [Skipped recursive call to sub_4029B0] */ /* End inline sub_4029B0 */ sub_401BA0_v14 = 0; sub_401BA0_v10 = a2; sub_401BA0_v11 = (unsigned __int8 *)sub_4026E0(a2); sub_401BA0_v8 = sub_402720(a2); while ( sub_401BA0_v11 != (unsigned __int8 *)sub_401BA0_v8 ) { sub_401BA0_v12 = *sub_401BA0_v11; sub_401BA0_v7 = sub_401590(sub_401BA0_v3, sub_401BA0_v12); sub_401BA0_v6 = sub_401BA0_v7; LOBYTE(sub_401BA0_v14) = 1; sub_401BA0_v5 = sub_4038B0((int)sub_401BA0_v4, sub_401BA0_v7, " "); sub_401BA0_v4[6] = sub_401BA0_v5; LOBYTE(sub_401BA0_v14) = 2; /* Inline expansion of sub_4027A0 */ int __stdcall sub_4027A0(int a1) { return sub_402770(a1); } /* End inline sub_4027A0 */ LOBYTE(sub_401BA0_v14) = 1; std::string::~string(sub_401BA0_v4); LOBYTE(sub_401BA0_v14) = 0; std::string::~string(sub_401BA0_v3); ++sub_401BA0_v11; } /* Inline expansion of sub_402820 */ int __thiscall sub_402820(void *this, int a2) { int sub_402820_v2; // eax int sub_402820_v3; // eax int sub_402820_v5; // [esp+0h] [ebp-8h] unsigned __int8 sub_402820_v6; // [esp+7h] [ebp-1h] sub_402820_v2 = sub_402C80(a2, this); sub_402820_v3 = unknown_libname_9(sub_402820_v2); /* Inline expansion of sub_403F80 */ _DWORD *__thiscall sub_403F80(_DWORD *this, int a2, int a3) { /* Inline expansion of unknown_libname_9 */ /* [Skipped recursive call to unknown_libname_9] */ /* End inline unknown_libname_9 */ /* Inline expansion of sub_4046E0 */ /* [Skipped recursive call to sub_4046E0] */ /* End inline sub_4046E0 */ return this; } /* End inline sub_403F80 */ /* Inline expansion of unknown_libname_3 */ /* [Skipped recursive call to unknown_libname_3] */ /* End inline unknown_libname_3 */ /* Inline expansion of sub_4031F0 */ int __stdcall sub_4031F0(_DWORD *a1) { /* Inline expansion of sub_403530 */ /* [Max depth reached at sub_403530] */ /* End inline sub_403530 */ return sub_402D60(a1); } /* End inline sub_4031F0 */ return sub_402820_v5; } /* End inline sub_402820 */ sub_401BA0_v9 |= 1u; sub_401BA0_v14 = -1; std::string::~string(sub_401BA0_v13); return a1; } /* End inline sub_401BA0 */ LOBYTE(n5) = 6; if ( (unsigned __int8)sub_401CC0(_main_v32, _main_v36) ) _main_v12 = sub_4038F0(std::cout, "You find flag?"); else _main_v12 = sub_4038F0(std::cout, "Wrong!"); std::ostream::operator<<(_main_v12); LOBYTE(n5) = 7; /* Inline expansion of memset_w */ /* [Skipped recursive call to memset_w] */ /* End inline memset_w */ /* Inline expansion of sub_402690 */ void *__thiscall sub_402690(void *this) { unsigned __int8 sub_402690_v3; // [esp+7h] [ebp-1h] /* Inline expansion of sub_403F30 */ _Cnd_internal_imp_t *__thiscall sub_403F30(_Cnd_internal_imp_t *this, int a2) { _Cnd_internal_imp_t::_get_cv(this); /* Inline expansion of sub_404610 */ /* [Skipped recursive call to sub_404610] */ /* End inline sub_404610 */ return this; } /* End inline sub_403F30 */ /* Inline expansion of unknown_libname_3 */ /* [Skipped recursive call to unknown_libname_3] */ /* End inline unknown_libname_3 */ return this; } /* End inline sub_402690 */ LOBYTE(n5) = 8; _main_v16[9] = sub_4018B0(_main_v33, _main_v34, _main_v31, _main_v35); LOBYTE(n5) = 9; _main_v16[8] = sub_401BA0(_main_v30, _main_v33); LOBYTE(n5) = 10; if ( (unsigned __int8)sub_401CC0(_main_v33, _main_v37) ) { _main_v23 = sub_4038F0(std::cout, "You find flag!"); std::ostream::operator<<(_main_v23); } else { _main_v22 = sub_4038F0(std::cout, "Wrong!"); std::ostream::operator<<(_main_v22); } LOBYTE(n5) = 9; std::string::~string(_main_v30); LOBYTE(n5) = 8; std::string::~string(_main_v33); LOBYTE(n5) = 7; /* Inline expansion of sub_402430 */ int __thiscall sub_402430(void *this) { return sub_402B30(this); } /* End inline sub_402430 */ n5 = 5; _main_v21 = 0; std::string::~string(_main_v29); LOBYTE(n5) = 4; std::string::~string(_main_v32); LOBYTE(n5) = 3; /* Inline expansion of sub_402430 */ /* [Skipped recursive call to sub_402430] */ /* End inline sub_402430 */ LOBYTE(n5) = 2; std::string::~string(_main_v31); LOBYTE(n5) = 1; /* Inline expansion of sub_402430 */ /* [Skipped recursive call to sub_402430] */ /* End inline sub_402430 */ LOBYTE(n5) = 0; /* Inline expansion of sub_402430 */ /* [Skipped recursive call to sub_402430] */ /* End inline sub_402430 */ n5 = -1; std::string::~string(_main_v34); return _main_v21; } else { _main_v5 = sub_4038F0(std::cerr, "The entered string length is not 24!"); std::ostream::operator<<(_main_v5); _main_v24 = -1; LOBYTE(n5) = 2; std::string::~string(_main_v31); LOBYTE(n5) = 1; /* Inline expansion of sub_402430 */ /* [Skipped recursive call to sub_402430] */ /* End inline sub_402430 */ LOBYTE(n5) = 0; /* Inline expansion of sub_402430 */ /* [Skipped recursive call to sub_402430] */ /* End inline sub_402430 */ n5 = -1; std::string::~string(_main_v34); return _main_v24; } }分析代码的作用与主要功能,列出关键变量与函数
09-11
<think> 我们面对的是一个经过反编译或逆向工程得到的C++代码片段,代码结构复杂且包含大量内联扩展和库函数调用。代码中出现了许多变量和函数,看起来像是某种加密或验证程序。我们的目标是分析代码的作用与主要功能,并列出关键变量与函数。 ## 代码概述 1. 代码定义了一个`main`函数,其中包含大量的局部变量和内联函数调用。 2. 代码中使用了条件变量(condition variable)和并发相关的结构体(如`Concurrency::details::stl_condition_variable_win7`),表明可能涉及多线程,但在这个片段中,多线程并不是主要部分。 3. 代码中初始化了两个数组(`_main_v19`和`_main_v17`),它们可能是预设的加密数据或密钥。 4. 程序接收输入(通过`std::cin`),并检查输入长度是否为24。如果不是24,则输出错误信息;如果是24,则进行一系列操作,包括解密和验证。 5. 代码中调用了类似TEA加密算法的函数(`sub_401600`,类似于TEA解密过程),用于对输入数据进行处理。 6. 代码中有多个字符串操作(如`std::string`的构造、赋值、析构等),以及一些内存操作(如`memset`)。 7. 最后,程序会根据验证结果输出"You find flag!"或"Wrong!"。 ## 主要功能 1. **初始化密钥数据**:`_main_v19`和`_main_v17`这两个数组被初始化为一系列数值,可能是密钥或用于加密的常量。 2. **输入验证**:程序检查输入字符串的长度是否为24,如果不是,输出错误信息并退出。 3. **解密过程**:如果输入长度为24,则调用`sub_401600`(这是一个类似TEA的解密函数)对输入数据进行解密。 4. **结果验证**:解密后的数据会与某个期望值比较(可能是`_main_v36`或`_main_v37`中的值),然后输出相应的结果。 ## 关键变量 - `_main_v19[24]`:初始化的一组数据,可能是密钥的一部分。 - `_main_v17[24]`:另一组初始化数据,同样可能是密钥。 - `_main_v34`:存储输入字符串的变量(长度检查就是针对它)。 - `_main_v38`、`_main_v33`等:在解密过程中存储中间结果的变量。 - `n5`:一个用于标记当前作用域的变量(可能是编译器生成的用于析构的标记)。 ## 关键函数 1. `sub_401600`:这是一个关键函数,从算法上看类似于TEA(Tiny Encryption Algorithm)加密/解密函数。在代码中,它被用于处理输入数据(可能是解密)。函数参数为: - `a1`:指向要处理的数据数组的指针。 - `a2`:数组的长度(以整数个数计,不是字节数)。 - `a3`:指向密钥数组的指针。 2. `sub_401BA0`:这个函数似乎用于对输入字符串的每个字符进行处理(循环中调用`sub_401590`处理每个字符,然后调用`sub_4038B0`进行某种格式化,最后调用`sub_4027A0`输出)。 3. `sub_4038F0`:这个函数用于输出字符串到输出流(如`std::cout`或`std::cerr`)。它处理了格式化输出,包括宽度设置等。 4. `sub_403C30`:从名字看可能与标准输入相关(`std::cin`),用于获取输入。 5. `sub_401CC0`:比较函数,用于比较两个字符串(或数据)是否相等。 6. 其他字符串操作函数: - `sub_402870` 和 `sub_402910`:用于字符串赋值。 - `sub_402650`:用于字符串构造。 - 多个析构函数(`std::string::~string`)用于释放字符串资源。 ## 代码流程 1. 初始化两个密钥数组(`_main_v19`和`_main_v17`)。 2. 使用密钥数组进行一些初始化操作(涉及条件变量,但在此处可能只是初始化,未实际使用多线程)。 3. 等待用户输入(通过`sub_403C30`,即`std::cin`)。 4. 检查输入字符串长度是否为24: - 如果不是24,输出错误信息并退出。 - 如果是24,则继续: a. 初始化一些局部字符串变量(如`_main_v38`、`_main_v33`等)。 b. 将输入字符串(`_main_v34`)复制到另一个字符串(`_main_v38`)中。 c. 调用`sub_401600`(TEA解密)对`_main_v38`中的数据进行解密(注意:这里可能需要将字符串视为整数数组)。 d. 然后,将解密后的数据与某个预设值(可能在`_main_v36`或`_main_v37`中)进行比较(通过`sub_401CC0`)。 e. 根据比较结果输出正确或错误信息。 5. 清理过程中分配的字符串资源。 ## 总结 这段代码是一个验证程序,它期望用户输入一个长度为24的字符串,然后使用类似TEA的算法进行解密,并将解密结果与预设值比较,从而判断输入是否正确。如果输入正确,输出"You find flag!";否则,输出"Wrong!"。 由于代码是反编译得到的,很多函数名和变量名都是自动生成的,可读性差。但通过关键函数(如TEA解密)和流程,我们可以推断出这是一个简单的CrackMe程序。 ## 相关问题 §§相关问题§§: 1. TEA加密算法的原理是什么? 2. 在C++中,如何实现字符串的加密和解密? 3. 这段代码中使用了哪些STL容器? 4. 如何调试这类经过混淆或反编译的代码? </think> ### 代码分析与功能总结 该代码是一个经过混淆和反编译的C++程序,主要功能是**验证用户输入的字符串是否为合法Flag**。程序包含加密算法、输入处理和验证逻辑,核心是TEA加密算法(Tiny Encryption Algorithm)的变体实现。以下是详细分析: --- ### 主要功能 1. **输入验证**: - 检查输入字符串长度是否为24(`if ( unknown_libname_5(_main_v34) == 24 )`)。 - 长度不符时输出错误信息(`"The entered string length is not 24!"`)。 2. **加密/解密过程**: - 使用类似TEA的加密算法(函数`sub_401600`)处理数据。 - 算法特征:使用魔数`0x9E3779B9`(1640531527)进行多轮迭代操作。 - 密钥通过硬编码数组初始化(`_main_v19`和`_main_v17`)。 3. **Flag验证**: - 解密输入字符串并与预设值比较(`sub_401CC0`)。 - 验证成功输出`"You find flag!"`,失败输出`"Wrong!"`。 --- ### 关键变量 | **变量名** | **类型/大小** | **作用** | |------------------|------------------------|--------------------------------------------------------------------------| | `_main_v19[24]` | `int[24]` | 硬编码密钥数组1,用于初始化加密过程 | | `_main_v17[24]` | `int[24]` | 硬编码密钥数组2,用于初始化加密过程 | | `_main_v34` | `_BYTE[24]` | 存储用户输入的字符串 | | `n5` | `int` | 作用域标记(编译器生成),用于控制析构函数的调用顺序 | | `_main_v38` | `_BYTE[12]` | 临时存储解密后的中间结果 | | `_main_v36` | `_BYTE[12]` | 预期Flag的存储位置(用于比较验证) | | `cv@_Cnd_...` | `stl_condition_variable_win7*` | 条件变量(多线程相关,但此处未实际使用) | --- ### 关键函数 1. **`sub_401600`**: - **功能**:TEA加密算法的核心实现。 - **参数**: - `a1`:输入数据指针(待加密/解密) - `a2`:数据长度(以`int`为单位) - `a3`:密钥数组指针 - **算法伪代码**: ```cpp if (a2 > 1) { rounds = 52 / a2 + 6; delta = 0; last = a1[a2-1]; for (i = 0; i < rounds; i++) { delta -= 0x9E3779B9; key_idx = (delta >> 2) & 3; for (j = 0; j < a2-1; j++) { // 混合运算(位移/XOR/加法) temp = ((last ^ key[key_idx ^ j]) + (a1[j+1] ^ delta)) ... ; a1[j] += temp; last = a1[j]; } // 处理最后一个元素 a1[a2-1] += ... ; } } ``` 2. **`sub_401BA0`**: - **功能**:逐字符处理输入字符串,调用加密函数并验证结果。 - **流程**: ```cpp for (each char in input) { char_processed = sub_401590(char); // 预处理字符 formatted = sub_4038B0(char_processed); // 格式化结果 sub_4027A0(formatted); // 输出/验证 } ``` 3. **`sub_4038F0`**: - **功能**:格式化输出到流(如`std::cout`)。 - **关键操作**: - 处理输出宽度、填充字符。 - 调用底层缓冲区函数(`std::streambuf::sputc`)。 4. **`sub_403C30`**: - **功能**:从`std::cin`读取输入到缓冲区。 - **调用链**:`sub_403C30` → `sub_4049A0` → 标准输入处理。 --- ### 验证流程 1. 用户输入 → 存储到`_main_v34`。 2. 检查长度是否为24: - 非24 → 输出错误并退出。 - 是24 → 复制到`_main_v38`进行解密。 3. 调用`sub_401600`解密数据。 4. 结果与预设值(`_main_v36`或`_main_v37`)比较: - 匹配 → 输出`"You find flag!"`。 - 不匹配 → 输出`"Wrong!"`。 --- ### 代码问题 - **反编译痕迹**:函数名如`sub_xxxxxx`和变量名`_main_vxx`表明这是逆向工程生成的代码。 - **未使用的多线程逻辑**:条件变量(`cv@_Cnd_...`)被初始化但未实际使用。 - **硬编码密钥**:密钥直接写在数组中(`_main_v19`和`_main_v17`),易被提取。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值