├── .gitignore ├── LICENSE ├── README.md ├── include └── sc4cpp.h ├── src ├── sc4cpp.cpp ├── sc4cpp.sln ├── sc4cpp.vcxproj ├── sc4cpp.vcxproj.filters └── scextractor.py └── test ├── README.md ├── msgbox_x64.sc ├── msgbox_x86.sc ├── runsc ├── runsc.cpp ├── runsc.sln ├── runsc.vcxproj └── runsc.vcxproj.filters ├── runsc_x64.exe └── runsc_x86.exe /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 windpiaoxue 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sc4cpp 2 | sc4cpp is a shellcode framework based on C++ 3 | 4 | ## Compiler 5 | Clang for Windows 6 | 7 | ## Compiler options 8 | ``` 9 | /O2 /Os /MT /GS- /Gs1048576 -mno-sse 10 | ``` 11 | 12 | ## Example 13 | ```cpp 14 | SC_NOINLINE 15 | SC_CODESEG_REORDERING 16 | DWORD WINAPI WorkerThread(PVOID lpAnsiMsg) { 17 | SC_IMPORT_API_BATCH_BEGIN(); 18 | SC_IMPORT_API_BATCH("User32.dll", MessageBoxA); 19 | SC_IMPORT_API_BATCH("User32.dll", MessageBoxW); 20 | SC_IMPORT_API_BATCH_END(); 21 | 22 | MessageBoxA(NULL, (PCSTR)lpAnsiMsg, SC_PISTRINGA("Hello!"), MB_OK); 23 | MessageBoxW(NULL, SC_PISTRINGW(L"Hello Unicode!"), SC_PISTRINGW(L"Hello!"), MB_OK); 24 | 25 | return 0; 26 | } 27 | 28 | SC_MAIN_BEGIN() 29 | { 30 | SC_IMPORT_API_BATCH_BEGIN(); 31 | SC_IMPORT_API_BATCH("Kernel32.dll", CreateThread); 32 | SC_IMPORT_API_BATCH("Kernel32.dll", WaitForSingleObject); 33 | SC_IMPORT_API_BATCH("Kernel32.dll", ExitProcess); 34 | SC_IMPORT_API_BATCH_END(); 35 | 36 | HANDLE hWorker = 37 | CreateThread(NULL, 0, SC_PIFUNCTION(WorkerThread), SC_PISTRINGA("Hello Ansi!"), 0, NULL); 38 | WaitForSingleObject(hWorker, INFINITE); 39 | 40 | ExitProcess(0); 41 | } 42 | SC_MAIN_END() 43 | ``` 44 | 45 | ## Example assembly output 46 | ```asm 47 | ; Segment type: Pure code 48 | seg000 segment byte public 'CODE' use32 49 | assume cs:seg000 50 | assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing 51 | call $+5 52 | pop eax 53 | lea eax, [eax-5] 54 | lea ecx, ds:405000h 55 | neg ecx 56 | lea eax, [eax+ecx+40501Ch] 57 | push eax 58 | call eax 59 | retn 60 | ; --------------------------------------------------------------------------- 61 | push ebp 62 | push ebx 63 | push edi 64 | push esi 65 | sub esp, 38h 66 | mov eax, dword ptr fs:loc_2F+1 67 | mov eax, [eax+0Ch] 68 | mov eax, [eax+14h] 69 | 70 | loc_2F: ; DATA XREF: seg000:00000023↑r 71 | ; seg000:loc_10D↓r ... 72 | mov ecx, eax 73 | 74 | loc_31: ; CODE XREF: seg000:000000FE↓j 75 | mov edi, [ecx+10h] 76 | mov ecx, [ecx] 77 | test edi, edi 78 | jz loc_FC 79 | mov edx, [edi+3Ch] 80 | mov edx, [edi+edx+78h] 81 | test edx, edx 82 | jz loc_FC 83 | mov esi, [edi+edx+0Ch] 84 | mov bl, [edi+esi] 85 | test bl, bl 86 | jz loc_FC 87 | mov [esp+4], edi 88 | lea esi, [edi+esi+1] 89 | mov edi, 811C9DC5h 90 | 91 | loc_69: ; CODE XREF: seg000:0000008D↓j 92 | mov bh, bl 93 | movzx ebp, bl 94 | add bl, 20h ; ' ' 95 | add bh, 0BFh 96 | cmp bh, 1Ah 97 | movzx ebx, bl 98 | cmovnb ebx, ebp 99 | movzx ebx, bl 100 | xor ebx, edi 101 | imul edi, ebx, 1000193h 102 | mov bl, [esi] 103 | inc esi 104 | test bl, bl 105 | jnz short loc_69 106 | mov esi, [esp+4] 107 | cmp edi, 0A3E6F6C3h 108 | jnz short loc_FC 109 | mov ebx, [esi+edx+18h] 110 | test ebx, ebx 111 | jz short loc_FC 112 | mov ebp, [esi+edx+20h] 113 | lea edi, [esi+1] 114 | mov [esp], ebx 115 | mov [esp+0Ch], edi 116 | xor edi, edi 117 | add ebp, esi 118 | mov [esp+8], ebp 119 | 120 | loc_B9: ; CODE XREF: seg000:000000FA↓j 121 | mov ebp, [ebp+edi*4+0] 122 | mov bl, [esi+ebp] 123 | test bl, bl 124 | jz short loc_EC 125 | add ebp, [esp+0Ch] 126 | mov esi, 811C9DC5h 127 | 128 | loc_CD: ; CODE XREF: seg000:000000DE↓j 129 | movzx ebx, bl 130 | xor ebx, esi 131 | imul esi, ebx, 1000193h 132 | mov bl, [ebp+0] 133 | inc ebp 134 | test bl, bl 135 | jnz short loc_CD 136 | cmp esi, 53B2070Fh 137 | jz loc_2F9 138 | 139 | loc_EC: ; CODE XREF: seg000:000000C2↑j 140 | mov ebx, [esp] 141 | mov esi, [esp+4] 142 | mov ebp, [esp+8] 143 | inc edi 144 | cmp edi, ebx 145 | jnz short loc_B9 146 | 147 | loc_FC: ; CODE XREF: seg000:00000038↑j 148 | ; seg000:00000047↑j ... 149 | cmp ecx, eax 150 | jnz loc_31 151 | int 3 ; Trap to Debugger 152 | mov dword ptr [esp+4], 0 153 | 154 | loc_10D: ; CODE XREF: seg000:00000314↓j 155 | mov eax, dword ptr fs:loc_2F+1 156 | mov eax, [eax+0Ch] 157 | mov eax, [eax+14h] 158 | mov ecx, eax 159 | 160 | loc_11B: ; CODE XREF: seg000:000001E7↓j 161 | mov ebp, [ecx+10h] 162 | mov ecx, [ecx] 163 | test ebp, ebp 164 | jz loc_1E5 165 | mov edx, [ebp+3Ch] 166 | mov edx, [ebp+edx+78h] 167 | test edx, edx 168 | jz loc_1E5 169 | mov esi, [ebp+edx+0Ch] 170 | mov bl, [ebp+esi+0] 171 | test bl, bl 172 | jz loc_1E5 173 | lea esi, [ebp+esi+1] 174 | mov edi, 811C9DC5h 175 | mov [esp], edx 176 | 177 | loc_153: ; CODE XREF: seg000:00000177↓j 178 | mov bh, bl 179 | movzx edx, bl 180 | add bl, 20h ; ' ' 181 | add bh, 0BFh 182 | cmp bh, 1Ah 183 | movzx ebx, bl 184 | cmovnb ebx, edx 185 | movzx edx, bl 186 | mov bl, [esi] 187 | inc esi 188 | xor edx, edi 189 | imul edi, edx, 1000193h 190 | test bl, bl 191 | jnz short loc_153 192 | mov edx, [esp] 193 | cmp edi, 0A3E6F6C3h 194 | jnz short loc_1E5 195 | mov esi, [ebp+edx+18h] 196 | test esi, esi 197 | jz short loc_1E5 198 | mov edx, [ebp+edx+20h] 199 | lea edi, [ebp+1] 200 | mov [esp+0Ch], edi 201 | xor edi, edi 202 | add edx, ebp 203 | mov [esp+8], edx 204 | 205 | loc_19F: ; CODE XREF: seg000:000001E3↓j 206 | mov ebx, [edx+edi*4] 207 | mov dl, [ebp+ebx+0] 208 | test dl, dl 209 | jz short loc_1DC 210 | add ebx, [esp+0Ch] 211 | mov [esp+10h], esi 212 | mov esi, 811C9DC5h 213 | 214 | loc_1B7: ; CODE XREF: seg000:000001C7↓j 215 | movzx edx, dl 216 | xor edx, esi 217 | imul esi, edx, 1000193h 218 | mov dl, [ebx] 219 | inc ebx 220 | test dl, dl 221 | jnz short loc_1B7 222 | cmp esi, 0F8F45725h 223 | mov edx, [esp] 224 | mov esi, [esp+10h] 225 | jz loc_319 226 | 227 | loc_1DC: ; CODE XREF: seg000:000001A8↑j 228 | mov edx, [esp+8] 229 | inc edi 230 | cmp edi, esi 231 | jnz short loc_19F 232 | 233 | loc_1E5: ; CODE XREF: seg000:00000122↑j 234 | ; seg000:00000131↑j ... 235 | cmp ecx, eax 236 | jnz loc_11B 237 | int 3 ; Trap to Debugger 238 | xor ebp, ebp 239 | 240 | loc_1F0: ; CODE XREF: seg000:0000032C↓j 241 | lea esi, [esp+14h] 242 | mov ecx, 6E72654Bh 243 | lea edi, [esp+24h] 244 | xor eax, eax 245 | mov edx, 6C6C642Eh 246 | mov [esi], ecx 247 | mov ecx, 32336C65h 248 | mov dword ptr [edi], 61657243h 249 | mov dword ptr [edi+4], 68546574h 250 | mov dword ptr [edi+8], 64616572h 251 | mov [edi+0Ch], al 252 | mov [esi+4], ecx 253 | mov [esi+8], edx 254 | mov [esi+0Ch], al 255 | push esi 256 | mov ebx, [esp+8] 257 | call ebx 258 | push edi 259 | push eax 260 | call ebp 261 | mov [esp], eax 262 | mov eax, 6E72654Bh 263 | mov dword ptr [edi], 74696157h 264 | mov dword ptr [edi+4], 53726F46h 265 | mov dword ptr [edi+8], 6C676E69h 266 | mov dword ptr [edi+0Ch], 6A624F65h 267 | mov dword ptr [edi+10h], 746365h 268 | mov [esi], eax 269 | mov eax, 32336C65h 270 | mov [esi+4], eax 271 | mov eax, 6C6C642Eh 272 | mov [esi+8], eax 273 | xor eax, eax 274 | mov [esi+0Ch], al 275 | push esi 276 | call ebx 277 | push edi 278 | push eax 279 | call ebp 280 | mov [esp+8], eax 281 | mov eax, 6E72654Bh 282 | mov dword ptr [esi], 74697845h 283 | mov dword ptr [esi+4], 636F7250h 284 | mov dword ptr [esi+8], 737365h 285 | mov [edi], eax 286 | mov eax, 32336C65h 287 | mov [edi+4], eax 288 | mov eax, 6C6C642Eh 289 | mov [edi+8], eax 290 | xor eax, eax 291 | mov [edi+0Ch], al 292 | push edi 293 | call ebx 294 | push esi 295 | push eax 296 | call ebp 297 | mov ebp, eax 298 | mov eax, 40501Ch 299 | mov ecx, 405331h 300 | mov dword ptr [edi], 6C6C6548h 301 | mov dword ptr [edi+4], 6E41206Fh 302 | mov dword ptr [edi+8], 216973h 303 | sub ecx, eax 304 | mov eax, [esp+4Ch] 305 | add eax, ecx 306 | xor ecx, ecx 307 | push ecx 308 | push ecx 309 | push edi 310 | push eax 311 | push ecx 312 | push ecx 313 | xor esi, esi 314 | call dword ptr [esp+18h] 315 | push 0FFFFFFFFh 316 | push eax 317 | call dword ptr [esp+10h] 318 | push esi 319 | call ebp 320 | 321 | loc_2F9: ; CODE XREF: seg000:000000E6↑j 322 | mov esi, [esp+4] 323 | mov eax, [esi+edx+24h] 324 | mov ecx, [esi+edx+1Ch] 325 | add eax, esi 326 | add ecx, esi 327 | movzx eax, word ptr [eax+edi*2] 328 | add esi, [ecx+eax*4] 329 | mov [esp+4], esi 330 | jmp loc_10D 331 | ; --------------------------------------------------------------------------- 332 | 333 | loc_319: ; CODE XREF: seg000:000001D6↑j 334 | mov eax, [ebp+edx+24h] 335 | mov ecx, [ebp+edx+1Ch] 336 | add eax, ebp 337 | add ecx, ebp 338 | movzx eax, word ptr [eax+edi*2] 339 | add ebp, [ecx+eax*4] 340 | jmp loc_1F0 341 | ; --------------------------------------------------------------------------- 342 | push ebp 343 | push ebx 344 | push edi 345 | push esi 346 | sub esp, 44h 347 | mov eax, dword ptr fs:loc_2F+1 348 | mov eax, [eax+0Ch] 349 | mov ecx, [eax+14h] 350 | mov [esp+4], ecx 351 | 352 | loc_348: ; CODE XREF: seg000:00000412↓j 353 | mov edx, [ecx+10h] 354 | mov ecx, [ecx] 355 | test edx, edx 356 | jz loc_40E 357 | mov eax, [edx+3Ch] 358 | mov esi, [edx+eax+78h] 359 | test esi, esi 360 | mov eax, esi 361 | mov [esp], esi 362 | jz loc_40E 363 | mov eax, [esp] 364 | mov eax, [edx+eax+0Ch] 365 | mov bl, [edx+eax] 366 | test bl, bl 367 | jz loc_40E 368 | lea eax, [edx+eax+1] 369 | mov edi, 811C9DC5h 370 | mov [esp+8], edx 371 | 372 | loc_388: ; CODE XREF: seg000:000003AC↓j 373 | mov edx, ebx 374 | movzx esi, bl 375 | add bl, 20h ; ' ' 376 | add dl, 0BFh 377 | cmp dl, 1Ah 378 | movzx edx, bl 379 | mov bl, [eax] 380 | cmovnb edx, esi 381 | inc eax 382 | movzx edx, dl 383 | xor edx, edi 384 | imul edi, edx, 1000193h 385 | test bl, bl 386 | jnz short loc_388 387 | mov esi, [esp+8] 388 | cmp edi, 0A3E6F6C3h 389 | jnz short loc_40E 390 | mov eax, [esp] 391 | mov edi, [esi+eax+18h] 392 | test edi, edi 393 | jz short loc_40E 394 | mov eax, [esp] 395 | xor ebx, ebx 396 | mov ebp, [esi+eax+20h] 397 | lea eax, [esi+1] 398 | mov [esp+0Ch], eax 399 | add ebp, esi 400 | 401 | loc_3D7: ; CODE XREF: seg000:0000040C↓j 402 | mov edx, [ebp+ebx*4+0] 403 | mov al, [esi+edx] 404 | test al, al 405 | jz short loc_409 406 | add edx, [esp+0Ch] 407 | mov esi, 811C9DC5h 408 | 409 | loc_3EB: ; CODE XREF: seg000:000003FB↓j 410 | movzx eax, al 411 | xor eax, esi 412 | imul esi, eax, 1000193h 413 | mov al, [edx] 414 | inc edx 415 | test al, al 416 | jnz short loc_3EB 417 | cmp esi, 53B2070Fh 418 | mov esi, [esp+8] 419 | jz short loc_41D 420 | 421 | loc_409: ; CODE XREF: seg000:000003E0↑j 422 | inc ebx 423 | cmp ebx, edi 424 | jnz short loc_3D7 425 | 426 | loc_40E: ; CODE XREF: seg000:0000034F↑j 427 | ; seg000:00000363↑j ... 428 | cmp ecx, [esp+4] 429 | jnz loc_348 430 | int 3 ; Trap to Debugger 431 | xor esi, esi 432 | jmp short loc_433 433 | ; --------------------------------------------------------------------------- 434 | 435 | loc_41D: ; CODE XREF: seg000:00000407↑j 436 | mov ecx, [esp] 437 | mov eax, [esi+ecx+24h] 438 | mov ecx, [esi+ecx+1Ch] 439 | add eax, esi 440 | add ecx, esi 441 | movzx eax, word ptr [eax+ebx*2] 442 | add esi, [ecx+eax*4] 443 | 444 | loc_433: ; CODE XREF: seg000:0000041B↑j 445 | mov [esp+8], esi 446 | mov eax, dword ptr fs:loc_2F+1 447 | mov eax, [eax+0Ch] 448 | mov eax, [eax+14h] 449 | mov [esp+0Ch], eax 450 | 451 | loc_447: ; CODE XREF: seg000:00000510↓j 452 | mov ebp, [eax+10h] 453 | mov eax, [eax] 454 | test ebp, ebp 455 | mov [esp], eax 456 | jz loc_509 457 | mov eax, [ebp+3Ch] 458 | mov ecx, [ebp+eax+78h] 459 | test ecx, ecx 460 | mov eax, ecx 461 | mov [esp+4], ecx 462 | jz loc_509 463 | mov eax, [esp+4] 464 | mov eax, [ebp+eax+0Ch] 465 | mov bl, [ebp+eax+0] 466 | test bl, bl 467 | jz loc_509 468 | lea eax, [ebp+eax+1] 469 | mov edx, 811C9DC5h 470 | 471 | loc_489: ; CODE XREF: seg000:000004AD↓j 472 | mov ecx, ebx 473 | movzx esi, bl 474 | add bl, 20h ; ' ' 475 | add cl, 0BFh 476 | cmp cl, 1Ah 477 | movzx ecx, bl 478 | mov bl, [eax] 479 | cmovnb ecx, esi 480 | inc eax 481 | movzx ecx, cl 482 | xor ecx, edx 483 | imul edx, ecx, 1000193h 484 | test bl, bl 485 | jnz short loc_489 486 | cmp edx, 0A3E6F6C3h 487 | jnz short loc_509 488 | mov eax, [esp+4] 489 | mov edi, [ebp+eax+18h] 490 | test edi, edi 491 | jz short loc_509 492 | mov eax, [esp+4] 493 | lea ecx, [ebp+1] 494 | xor ebx, ebx 495 | mov [esp+10h], ecx 496 | mov eax, [ebp+eax+20h] 497 | add eax, ebp 498 | 499 | loc_4D6: ; CODE XREF: seg000:00000507↓j 500 | mov edx, [eax+ebx*4] 501 | mov cl, [ebp+edx+0] 502 | test cl, cl 503 | jz short loc_504 504 | add edx, [esp+10h] 505 | mov esi, 811C9DC5h 506 | 507 | loc_4EA: ; CODE XREF: seg000:000004FA↓j 508 | movzx ecx, cl 509 | xor ecx, esi 510 | imul esi, ecx, 1000193h 511 | mov cl, [edx] 512 | inc edx 513 | test cl, cl 514 | jnz short loc_4EA 515 | cmp esi, 0F8F45725h 516 | jz short loc_51B 517 | 518 | loc_504: ; CODE XREF: seg000:000004DF↑j 519 | inc ebx 520 | cmp ebx, edi 521 | jnz short loc_4D6 522 | 523 | loc_509: ; CODE XREF: seg000:00000451↑j 524 | ; seg000:00000466↑j ... 525 | mov eax, [esp] 526 | cmp eax, [esp+0Ch] 527 | jnz loc_447 528 | int 3 ; Trap to Debugger 529 | xor ebp, ebp 530 | jmp short loc_532 531 | ; --------------------------------------------------------------------------- 532 | 533 | loc_51B: ; CODE XREF: seg000:00000502↑j 534 | mov ecx, [esp+4] 535 | mov eax, [ebp+ecx+24h] 536 | mov ecx, [ebp+ecx+1Ch] 537 | add eax, ebp 538 | add ecx, ebp 539 | movzx eax, word ptr [eax+ebx*2] 540 | add ebp, [ecx+eax*4] 541 | 542 | loc_532: ; CODE XREF: seg000:00000519↑j 543 | mov eax, 7373654Dh 544 | lea ebx, [esp+24h] 545 | lea edi, [esp+14h] 546 | mov [ebx], eax 547 | mov eax, 42656761h 548 | mov [ebx+4], eax 549 | mov eax, 72657355h 550 | mov dword ptr [ebx+8], 41786Fh 551 | mov [edi], eax 552 | mov eax, 642E3233h 553 | mov [edi+4], eax 554 | mov ax, 6C6Ch 555 | mov [edi+8], ax 556 | xor eax, eax 557 | mov [edi+0Ah], al 558 | push edi 559 | mov esi, [esp+0Ch] 560 | call esi 561 | push ebx 562 | push eax 563 | call ebp 564 | mov [esp], eax 565 | mov eax, 7373654Dh 566 | mov [ebx], eax 567 | mov eax, 42656761h 568 | mov [ebx+4], eax 569 | mov eax, 72657355h 570 | mov dword ptr [ebx+8], 57786Fh 571 | mov [edi], eax 572 | mov eax, 642E3233h 573 | mov [edi+4], eax 574 | mov ax, 6C6Ch 575 | mov [edi+8], ax 576 | xor eax, eax 577 | mov [edi+0Ah], al 578 | push edi 579 | call esi 580 | push ebx 581 | push eax 582 | call ebp 583 | mov esi, eax 584 | xor eax, eax 585 | mov dword ptr [ebx], 6C6C6548h 586 | mov word ptr [ebx+4], 216Fh 587 | mov [ebx+6], al 588 | push eax 589 | push ebx 590 | push dword ptr [esp+60h] 591 | push eax 592 | xor ebp, ebp 593 | call dword ptr [esp+10h] 594 | mov eax, 650048h 595 | mov ecx, 6C006Ch 596 | mov [edi], eax 597 | mov [edi+4], ecx 598 | mov dword ptr [edi+8], 21006Fh 599 | mov [ebx], eax 600 | mov [ebx+4], ecx 601 | mov dword ptr [ebx+8], 20006Fh 602 | mov dword ptr [ebx+0Ch], 6E0055h 603 | mov dword ptr [ebx+10h], 630069h 604 | mov dword ptr [ebx+14h], 64006Fh 605 | mov dword ptr [ebx+18h], 210065h 606 | mov [edi+0Ch], bp 607 | mov [ebx+1Ch], bp 608 | push ebp 609 | push edi 610 | push ebx 611 | push ebp 612 | call esi 613 | xor eax, eax 614 | add esp, 44h 615 | pop esi 616 | pop edi 617 | pop ebx 618 | pop ebp 619 | retn 4 620 | seg000 ends 621 | ``` 622 | -------------------------------------------------------------------------------- /include/sc4cpp.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2021 smh 3 | * All rights reserved 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | #pragma once 24 | 25 | #if !defined(__clang__) || !defined(_WIN32) 26 | #error "sc4cpp only supports Clang on windows" 27 | #endif 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef _DEBUG 35 | #define SC_DEBUG 36 | #endif // _DEBUG 37 | 38 | #ifdef _WIN64 39 | #define SC_WIN64 40 | #endif // _WIN64 41 | 42 | #define SC_CONSTEXPR constexpr 43 | #define SC_NOINLINE __declspec(noinline) 44 | #define SC_FORCEINLINE __forceinline 45 | 46 | #define SC_EXTERN_C_BEGIN extern "C" { 47 | #define SC_DLL_IMPORT __declspec(dllimport) 48 | #define SC_DLL_EXPORT __declspec(dllexport) 49 | #define SC_EXTERN_C_END } 50 | 51 | #define SC_NAKEDFUNC __declspec(naked) 52 | #define SC_ASM __asm 53 | #define SC_EMIT(c) __asm _emit(c) 54 | 55 | #define SC_CODESEG(s) __declspec(code_seg(".code$" #s)) 56 | 57 | #define SC_CODESEG_START SC_CODESEG(CAA) 58 | #define SC_CODESEG_END SC_CODESEG(CZZ) 59 | #define SC_CODESEG_MAIN SC_CODESEG(CBA) 60 | 61 | // Make sure it is between MAIN and END. 62 | #define SC_CODESEG_REORDERING SC_CODESEG(CXI) 63 | 64 | namespace SC { 65 | // https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function 66 | template 67 | SC_FORCEINLINE SC_CONSTEXPR DWORD Hash(PCSTR lpName) { 68 | DWORD dwHash = 2166136261u; 69 | for (; *lpName != '\0'; ++lpName) { 70 | dwHash = (dwHash ^ (BYTE)Converter()(*lpName)) * 16777619ull; 71 | } 72 | return dwHash; 73 | } 74 | SC_FORCEINLINE SC_CONSTEXPR DWORD Hash(PCSTR lpName) { 75 | struct Converter { 76 | SC_CONSTEXPR Converter() {} 77 | SC_CONSTEXPR CHAR operator()(CHAR c) const { return c; } 78 | }; 79 | return Hash(lpName); 80 | } 81 | SC_FORCEINLINE SC_CONSTEXPR DWORD HashI(PCSTR lpName) { 82 | struct Converter { 83 | SC_CONSTEXPR Converter() {} 84 | SC_CONSTEXPR CHAR operator()(CHAR c) const { 85 | return c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c; 86 | } 87 | }; 88 | return Hash(lpName); 89 | } 90 | 91 | SC_FORCEINLINE PPEB GetPEB() { 92 | #ifdef _WIN64 93 | return (PPEB)__readgsqword(offsetof(TEB, ProcessEnvironmentBlock)); 94 | #else 95 | return (PPEB)__readfsdword(offsetof(TEB, ProcessEnvironmentBlock)); 96 | #endif // _WIN64 97 | } 98 | 99 | SC_FORCEINLINE PIMAGE_NT_HEADERS GetNTHeaders(PVOID lpDLLBase) { 100 | PIMAGE_DOS_HEADER lpDOSHeader = (PIMAGE_DOS_HEADER)lpDLLBase; 101 | return (PIMAGE_NT_HEADERS)((PBYTE)lpDLLBase + lpDOSHeader->e_lfanew); 102 | } 103 | 104 | SC_FORCEINLINE PLDR_DATA_TABLE_ENTRY GetDataTableEntry(PLIST_ENTRY lpList) { 105 | SIZE_T zuEntryOffset = offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); 106 | return (PLDR_DATA_TABLE_ENTRY)((LPBYTE)lpList - zuEntryOffset); 107 | } 108 | 109 | SC_FORCEINLINE PVOID GetProcAddressByHash(DWORD dwDLLHash, DWORD dwProcHash) { 110 | PLIST_ENTRY lpSentryNode = &GetPEB()->Ldr->InMemoryOrderModuleList; 111 | for (PLIST_ENTRY lpIterNode = lpSentryNode->Flink; 112 | lpIterNode != lpSentryNode; 113 | lpIterNode = lpIterNode->Flink) { 114 | PLDR_DATA_TABLE_ENTRY lpDLLEntry = GetDataTableEntry(lpIterNode); 115 | LPSTR lpDLLBase = (LPSTR)lpDLLEntry->DllBase; 116 | if (lpDLLBase == NULL) { 117 | continue; 118 | } 119 | PIMAGE_NT_HEADERS lpNTHeaders = GetNTHeaders(lpDLLBase); 120 | DWORD dwExportDirectoryRAV = 121 | lpNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; 122 | if (dwExportDirectoryRAV == 0) { 123 | continue; 124 | } 125 | PIMAGE_EXPORT_DIRECTORY lpExportDirectory = 126 | (PIMAGE_EXPORT_DIRECTORY)(lpDLLBase + dwExportDirectoryRAV); 127 | if (HashI(lpDLLBase + lpExportDirectory->Name) != dwDLLHash) { 128 | continue; 129 | } 130 | PDWORD lpNameRAVs = (PDWORD)(lpDLLBase + lpExportDirectory->AddressOfNames); 131 | PWORD lpOrdinals = (PWORD)(lpDLLBase + lpExportDirectory->AddressOfNameOrdinals); 132 | PDWORD lpProcRAVs = (PDWORD)(lpDLLBase + lpExportDirectory->AddressOfFunctions); 133 | for (DWORD dwIdx = 0; dwIdx < lpExportDirectory->NumberOfNames; ++dwIdx) { 134 | if (Hash(lpDLLBase + lpNameRAVs[dwIdx]) == dwProcHash) { 135 | // FIXME: DLL Function Forwarding 136 | return lpDLLBase + lpProcRAVs[lpOrdinals[dwIdx]]; 137 | } 138 | } 139 | } 140 | __debugbreak(); 141 | return NULL; // No return 142 | } 143 | 144 | // For Compile-time calculation 145 | template 146 | SC_FORCEINLINE PVOID GetProcAddressByHash() { 147 | return GetProcAddressByHash(dwDLLHash, dwProcHash); 148 | } 149 | 150 | // Position Independent String 151 | template 152 | struct PIString; 153 | template 154 | struct PIString> { 155 | CharType szBuffer_[sizeof...(Indices)]; 156 | SC_FORCEINLINE SC_CONSTEXPR explicit PIString(const CharType (&szLiteral)[sizeof...(Indices)]) 157 | : szBuffer_{(szLiteral[Indices])...} {} 158 | }; 159 | } // namespace SC 160 | 161 | #ifdef SC_WIN64 162 | #define SC_BEGIN_CODE \ 163 | SC_DLL_EXPORT SC_CODESEG_START VOID SCBegin() { SCMain(NULL); } 164 | #else 165 | // clang-format off 166 | #define SC_BEGIN_CODE \ 167 | SC_DLL_EXPORT SC_CODESEG_START SC_NAKEDFUNC VOID SCBegin() { \ 168 | /* CALL $+5 */ \ 169 | SC_EMIT(0xE8) SC_EMIT(0x00) SC_EMIT(0x00) SC_EMIT(0x00) SC_EMIT(0x00) \ 170 | SC_ASM POP EAX \ 171 | SC_ASM LEA EAX, [EAX - 5] \ 172 | SC_ASM LEA ECX, [SCBegin] \ 173 | SC_ASM NEG ECX \ 174 | SC_ASM LEA EAX, [EAX + ECX + SCMain] \ 175 | SC_ASM PUSH EAX \ 176 | SC_ASM CALL EAX \ 177 | SC_ASM RET \ 178 | } 179 | // clang-format on 180 | #endif // SC_WIN64 181 | 182 | #define SC_MAIN_BEGIN() \ 183 | SC_EXTERN_C_BEGIN \ 184 | SC_DLL_EXPORT VOID WINAPI SCMain(ULONG_PTR SCMainVA); \ 185 | SC_BEGIN_CODE \ 186 | SC_DLL_EXPORT SC_CODESEG_MAIN VOID WINAPI SCMain(ULONG_PTR SCMainVA) 187 | #define SC_MAIN_END() \ 188 | SC_DLL_EXPORT SC_CODESEG_END VOID SCEnd() { __debugbreak(); } \ 189 | SC_EXTERN_C_END 190 | 191 | #define SC_PISTRINGA(szLiteralA) \ 192 | (::SC::PIString>(szLiteralA).szBuffer_) 193 | #define SC_PISTRINGW(szLiteralW) \ 194 | (::SC::PIString>(szLiteralW).szBuffer_) 195 | 196 | #ifdef SC_WIN64 197 | #define SC_PIFUNCTION(fnReordered) ((decltype(fnReordered)*)fnReordered) 198 | #else 199 | // Must be invoked in SCMain. 200 | #define SC_PIFUNCTION(fnReordered) \ 201 | ((decltype(fnReordered)*)(((ULONG_PTR)(fnReordered) - (ULONG_PTR)SCMain) + SCMainVA)) 202 | #endif // SC_WIN64 203 | 204 | #define SC_GET_API_ADDRESS(szDLLName, szAPIName) \ 205 | (::SC::GetProcAddressByHash<::SC::HashI(szDLLName), ::SC::Hash(szAPIName)>()) 206 | 207 | #define SC_IMPORT_API_AS(fnVarName, szDLLName, fnAPIName) \ 208 | auto fnVarName = (decltype(::fnAPIName)*)SC_GET_API_ADDRESS(szDLLName, #fnAPIName) 209 | #define SC_IMPORT_API(szDLLName, fnAPIName) SC_IMPORT_API_AS(fnAPIName, szDLLName, fnAPIName) 210 | 211 | #define SC_IMPORT_API_BATCH_BEGIN() \ 212 | SC_IMPORT_API_AS(fnSCLoadLibraryA, "Kernel32.dll", LoadLibraryA); \ 213 | SC_IMPORT_API_AS(fnSCGetFnAddress, "Kernel32.dll", GetProcAddress) 214 | #define SC_IMPORT_API_BATCH(szDLLName, fnAPIName) \ 215 | auto fnAPIName = (decltype(::fnAPIName)*)(fnSCGetFnAddress( \ 216 | fnSCLoadLibraryA(SC_PISTRINGA(szDLLName)), SC_PISTRINGA(#fnAPIName))) 217 | #define SC_IMPORT_API_BATCH_END() 218 | -------------------------------------------------------------------------------- /src/sc4cpp.cpp: -------------------------------------------------------------------------------- 1 | #include "sc4cpp.h" 2 | 3 | // *** Place function definition here! *** 4 | 5 | SC_NOINLINE 6 | SC_CODESEG_REORDERING 7 | DWORD WINAPI WorkerThread(PVOID lpAnsiMsg) { 8 | SC_IMPORT_API_BATCH_BEGIN(); 9 | SC_IMPORT_API_BATCH("User32.dll", MessageBoxA); 10 | SC_IMPORT_API_BATCH("User32.dll", MessageBoxW); 11 | SC_IMPORT_API_BATCH_END(); 12 | 13 | MessageBoxA(NULL, (PCSTR)lpAnsiMsg, SC_PISTRINGA("Hello!"), MB_OK); 14 | MessageBoxW(NULL, SC_PISTRINGW(L"Hello Unicode!"), SC_PISTRINGW(L"Hello!"), MB_OK); 15 | 16 | return 0; 17 | } 18 | 19 | // clang-format off 20 | SC_MAIN_BEGIN() 21 | { 22 | // clang-format on 23 | SC_IMPORT_API_BATCH_BEGIN(); 24 | SC_IMPORT_API_BATCH("Kernel32.dll", CreateThread); 25 | SC_IMPORT_API_BATCH("Kernel32.dll", WaitForSingleObject); 26 | SC_IMPORT_API_BATCH("Kernel32.dll", ExitProcess); 27 | SC_IMPORT_API_BATCH_END(); 28 | 29 | // *** Place code here! *** 30 | 31 | HANDLE hWorker = 32 | CreateThread(NULL, 0, SC_PIFUNCTION(WorkerThread), SC_PISTRINGA("Hello Ansi!"), 0, NULL); 33 | WaitForSingleObject(hWorker, INFINITE); 34 | 35 | ExitProcess(0); 36 | // clang-format off 37 | } 38 | SC_MAIN_END() 39 | // clang-format on 40 | -------------------------------------------------------------------------------- /src/sc4cpp.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31129.286 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sc4cpp", "sc4cpp.vcxproj", "{947B670F-1CAE-425B-8630-0471FD8EEB73}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {947B670F-1CAE-425B-8630-0471FD8EEB73}.Debug|x64.ActiveCfg = Debug|x64 17 | {947B670F-1CAE-425B-8630-0471FD8EEB73}.Debug|x64.Build.0 = Debug|x64 18 | {947B670F-1CAE-425B-8630-0471FD8EEB73}.Debug|x86.ActiveCfg = Debug|Win32 19 | {947B670F-1CAE-425B-8630-0471FD8EEB73}.Debug|x86.Build.0 = Debug|Win32 20 | {947B670F-1CAE-425B-8630-0471FD8EEB73}.Release|x64.ActiveCfg = Release|x64 21 | {947B670F-1CAE-425B-8630-0471FD8EEB73}.Release|x64.Build.0 = Release|x64 22 | {947B670F-1CAE-425B-8630-0471FD8EEB73}.Release|x86.ActiveCfg = Release|Win32 23 | {947B670F-1CAE-425B-8630-0471FD8EEB73}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {BE9E5084-C8DC-4E23-AA78-565B96C545C0} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /src/sc4cpp.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {947b670f-1cae-425b-8630-0471fd8eeb73} 25 | sc4cpp 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | ClangCL 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | ClangCL 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | ClangCL 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | ClangCL 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 90 | true 91 | MultiThreadedDebug 92 | false 93 | false 94 | /Gs1048576 -mno-sse %(AdditionalOptions) 95 | $(SolutionDir)..\include;%(AdditionalIncludeDirectories) 96 | 97 | 98 | Windows 99 | true 100 | SCBegin 101 | 102 | 103 | python scextractor.py $(TargetPath) 104 | 105 | 106 | 107 | 108 | Level3 109 | true 110 | true 111 | true 112 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 113 | true 114 | MultiThreaded 115 | false 116 | false 117 | /Gs1048576 -mno-sse %(AdditionalOptions) 118 | $(SolutionDir)..\include;%(AdditionalIncludeDirectories) 119 | Size 120 | MaxSpeed 121 | 122 | 123 | Windows 124 | true 125 | true 126 | true 127 | SCBegin 128 | 129 | 130 | python scextractor.py $(TargetPath) 131 | 132 | 133 | 134 | 135 | Level3 136 | true 137 | _DEBUG;_WINDOWS;%(PreprocessorDefinitions) 138 | true 139 | MultiThreadedDebug 140 | false 141 | false 142 | /Gs1048576 -mno-sse %(AdditionalOptions) 143 | $(SolutionDir)..\include;%(AdditionalIncludeDirectories) 144 | 145 | 146 | Windows 147 | true 148 | SCBegin 149 | 150 | 151 | python scextractor.py $(TargetPath) 152 | 153 | 154 | 155 | 156 | Level3 157 | true 158 | true 159 | true 160 | NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 161 | true 162 | MultiThreaded 163 | false 164 | false 165 | /Gs1048576 -mno-sse %(AdditionalOptions) 166 | $(SolutionDir)..\include;%(AdditionalIncludeDirectories) 167 | Size 168 | MaxSpeed 169 | 170 | 171 | Windows 172 | true 173 | true 174 | true 175 | SCBegin 176 | 177 | 178 | python scextractor.py $(TargetPath) 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /src/sc4cpp.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/scextractor.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import pefile 4 | import sys 5 | from pathlib import Path 6 | 7 | 8 | def extract_shellcode(sc_path : Path) -> Path: 9 | image = pefile.PE(str(sc_path)) 10 | if not image.is_exe() and not image.is_dll(): 11 | raise Exception("The file is not a valid PE file.") 12 | 13 | for symbol in image.DIRECTORY_ENTRY_EXPORT.symbols: 14 | if symbol.name.decode() == "SCBegin": 15 | sc_begin = symbol.address 16 | elif symbol.name.decode() == "SCEnd": 17 | sc_end = symbol.address 18 | if "sc_begin" not in locals().keys() or "sc_end" not in locals().keys(): 19 | raise Exception("Not found shellcode in the PE file.") 20 | 21 | sc_path = sc_path.parent.joinpath(sc_path.stem).with_suffix(".sc") 22 | sc_path.write_bytes(image.get_data(sc_begin, sc_end - sc_begin)) 23 | return sc_path 24 | 25 | 26 | if __name__ == "__main__": 27 | if len(sys.argv) != 2: 28 | raise Exception("Invalid parameters.") 29 | sc_path = Path(sys.argv[1]) 30 | if not sc_path.is_file(): 31 | raise Exception("Invalid parameters.") 32 | sc_path = extract_shellcode(sc_path) 33 | print(f"------ The shellcode extracted successfully and saved {sc_path} ------") 34 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | Drop msgbox to runsc. -------------------------------------------------------------------------------- /test/msgbox_x64.sc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/windpiaoxue/sc4cpp/e252d9a55228303f3a8565b6a347c6d386dbb5d3/test/msgbox_x64.sc -------------------------------------------------------------------------------- /test/msgbox_x86.sc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/windpiaoxue/sc4cpp/e252d9a55228303f3a8565b6a347c6d386dbb5d3/test/msgbox_x86.sc -------------------------------------------------------------------------------- /test/runsc/runsc.cpp: -------------------------------------------------------------------------------- 1 | #define _CRT_SECURE_NO_WARNINGS 2 | #include 3 | #include 4 | #include 5 | 6 | int main(int argc, char* argv[]) { 7 | if (argc <= 1) { 8 | printf("Invalid parameters\n"); 9 | return 1; 10 | } 11 | std::ifstream file(argv[1], std::ios::binary); 12 | if (!file.is_open()) { 13 | printf("Failed to open the file: %s\n", strerror(errno)); 14 | return 1; 15 | } 16 | std::string sc(std::istreambuf_iterator{file}, std::istreambuf_iterator{}); 17 | void* buffer = VirtualAlloc( 18 | NULL, 19 | sc.length(), 20 | MEM_RESERVE | MEM_COMMIT, 21 | PAGE_EXECUTE_READWRITE); 22 | if (buffer == NULL) { 23 | printf("Failed to allocate memory: error=%u\n", GetLastError()); 24 | return 1; 25 | } 26 | memcpy(buffer, sc.c_str(), sc.length()); 27 | ((void(*)())buffer)(); 28 | } 29 | -------------------------------------------------------------------------------- /test/runsc/runsc.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31313.79 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runsc", "runsc.vcxproj", "{AADA0C7C-A849-4566-A6C6-699B68E35FB8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {AADA0C7C-A849-4566-A6C6-699B68E35FB8}.Debug|x64.ActiveCfg = Debug|x64 17 | {AADA0C7C-A849-4566-A6C6-699B68E35FB8}.Debug|x64.Build.0 = Debug|x64 18 | {AADA0C7C-A849-4566-A6C6-699B68E35FB8}.Debug|x86.ActiveCfg = Debug|Win32 19 | {AADA0C7C-A849-4566-A6C6-699B68E35FB8}.Debug|x86.Build.0 = Debug|Win32 20 | {AADA0C7C-A849-4566-A6C6-699B68E35FB8}.Release|x64.ActiveCfg = Release|x64 21 | {AADA0C7C-A849-4566-A6C6-699B68E35FB8}.Release|x64.Build.0 = Release|x64 22 | {AADA0C7C-A849-4566-A6C6-699B68E35FB8}.Release|x86.ActiveCfg = Release|Win32 23 | {AADA0C7C-A849-4566-A6C6-699B68E35FB8}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {9476F7C1-88D6-47B7-A817-E5AA297CD8A7} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /test/runsc/runsc.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {aada0c7c-a849-4566-a6c6-699b68e35fb8} 25 | runsc 26 | 10.0 27 | 28 | 29 | 30 | Application 31 | true 32 | v142 33 | Unicode 34 | 35 | 36 | Application 37 | false 38 | v142 39 | true 40 | Unicode 41 | 42 | 43 | Application 44 | true 45 | v142 46 | Unicode 47 | 48 | 49 | Application 50 | false 51 | v142 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | Level3 88 | true 89 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 90 | true 91 | MultiThreadedDebug 92 | 93 | 94 | Console 95 | true 96 | 97 | 98 | 99 | 100 | Level3 101 | true 102 | true 103 | true 104 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 105 | true 106 | MultiThreaded 107 | 108 | 109 | Console 110 | true 111 | true 112 | false 113 | 114 | 115 | 116 | 117 | Level3 118 | true 119 | _DEBUG;_CONSOLE;%(PreprocessorDefinitions) 120 | true 121 | MultiThreadedDebug 122 | 123 | 124 | Console 125 | true 126 | 127 | 128 | 129 | 130 | Level3 131 | true 132 | true 133 | true 134 | NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 135 | true 136 | MultiThreaded 137 | 138 | 139 | Console 140 | true 141 | true 142 | false 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /test/runsc/runsc.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 源文件 20 | 21 | 22 | -------------------------------------------------------------------------------- /test/runsc_x64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/windpiaoxue/sc4cpp/e252d9a55228303f3a8565b6a347c6d386dbb5d3/test/runsc_x64.exe -------------------------------------------------------------------------------- /test/runsc_x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/windpiaoxue/sc4cpp/e252d9a55228303f3a8565b6a347c6d386dbb5d3/test/runsc_x86.exe --------------------------------------------------------------------------------