"Lao Liu Talk about algorithm 003" command-line parameter processing and obtaining--ARGCL function implementation analysis

Source: Internet
Author: User

In non-assembly language, the processing and splitting of command-line arguments (cmdline) is generally done by the compiler to preset the processing code in the executable file or call the run-time library.
In the Assembly, we need to manually invoke the Windows Api--getcommandline function to get a messy string (containing the executable path and command-line arguments).
Fortunately in Masm32library, the assembly enthusiasts provided a function to get command-line arguments, eliminating the effort to build the wheels ourselves,
What does the function do with all sorts of cmdline that do not follow the routine? This has aroused my interest in analyzing this code.
Of course, the algorithm listed below and the disposition of special cases may be different from other languages, for reference only.
The algorithm flow is as follows:

The code is as follows:

Original source: MASM32 SDK; Comment Modification & Chinese comment add by Lao Liu;            #########################################################################;; This program was developed under the technical support of Iczelion and Lucifer.; #########################################################################. 386. Model flat, stdcall; -bit memory model option Casemap:none; Case sensitive include \masm32\include\kernel32.inc; ------------------------------------  ; Please read the final usage of the text; ------------------------------------ARGCL PROTO:D Word,:D Word. Code; ######################################################################## #ArgCl proc Argnum:dword, ItemBuffer:D Word local cmdline:D word local cmdbuffer[192]: Byte local tmpbuffer[192]: byte; --------------  ; Storage of ESI & EDI; --------------push ESI push edi invoke GetCommandLine mov cmdline, eax;                   Address command line CMP argnum, 0 jne @F xor eax, eax jmp jmp_in @@: mov esi, cmdline LODSB ; Al=byte ptr [ESI] cmp al, je @F; if not half-width double quotes, exit pop edi pop esi xor eax, eax; eax=0 ret @@:; -------------------------------------------------  ; Statistical quotation marks to confirm whether they match; -------------------------------------------------xor ecx, ECX;                  ECX as a counter to the number of quotes mov esi, cmdline @@: LODSB cmp al, 0; Reach End JE @F cmp al, 34                Jne @B; no quotes continue to Loop Inc ECX; ecx+=1 jmp @B @@: Push ECX Storage count Value shr ecx, 1 shl ecx, 1; ecx-=ecx%2 pop eax; eax= count value cmp eax,  Ecx JE @F; the number of quotes is even (matched) the next hop pop edi pop ESI mov eax, 3; return 3 ret @@: ; -------------------------------------------  ; The following code removes the (program's) path and file name; CmdLine only leaves parameters; -------------------------------------------mov esi, cmdline; esi=cmdline pointer Lea EDI, Tmpbuffer; EDI=TMPB  Uffer pointer  LODSB; Read the first quotation mark @@:; Remove the character until the second quotation mark is read LODSB cmp al, Jne @B WTIN:LODSB CMP al, 0 je wtout stosb; transfer to Tmpbuffer jmp wtin WTOUT:STOSB; Tmpbuffer end; -----------------------------------  ; Handling null Parameters "" (In fact, "->255");       -----------------------------------Lea ESI, Tmpbuffer Lea EDI, Cmdbuffer xor edx, edx, clear 0, using RNSST as a flag register:        LODSB cmp al, 0 je rnsend; ESI points to null, which is done. if al! = 34; The character is not quoted. if edx = = 1 ; The preceding character is quoted as an XOR edx, edx; edx=0 jmp rnswrt. endif. ElseIf Al = = 34; The character is a quotation mark. If Ed        x = = 1; the previous character is quoted Mov al, 255 STOSB; EDI points to address =255,edi++, in fact, is the quotation mark 255 mov al, 34 ; write another quotation mark STOSB Dec edx; edx=0 jmp rnsst. ElseIf edx = = 0 Inc ed x; mark. endif. endif RNSWRT:STOSB jmp rnsst RNSEND:STOSB; Cmdbuffer end; ----------------------------------  ; Replace the enclosed spaces with quotation marks (spaces->254 in quotation marks); Delete quotation marks (255 above "" will not be deleted);    ----------------------------------Lea ESI, Cmdbuffer; The following operation is the same address, but because the first read and write, does not conflict.      Lea EDI, Cmdbuffer SUBST:LODSB cmp al, 0 jne @F jmp subout; Complete @@: CMP al, 34 Jne subnxt jmp SUBSL; If you have quotes, enter the sub-loop SUBNXT:STOSB; write it back to JMP subSt;      --------------------------SUBSL:LODSB cmp al, 32; is a space jne @F mov al, 254; Space for 254 @@: CMP al, jne @F jmp subSt; loop complete, return to @@: STOSB; write it back to JMP SUBSL; --------------------------SUBOUT:STOSB; end; ------------------------    ; Tab--> space; ------------------------Lea ESI, Cmdbuffer Lea EDI, Cmdbuffer @@: LODSB cmp al, 0 JE rtout c MP Al, 9 jne rtin; Not for tab Jump mov al, 9-->32 rtin:      STOSB jmp @B RTOUT:STOSB; ----------------------------------------------------  ; The following code splits the correct arg; And the Arg is written to the destination address; ----------------------------------------------------lea eax, Cmdbuffer mov esi, eax mov edi, itembuffer; Target Address mov ecx, 1; Do the counter; ---------------------------  ; Remove the pilot space (if any); ---------------------------@@: LODSB cmp al, je @B l2st:cmp ecx, argnum; The Incoming argnum je clSubLp2; the location where you need to take the parameter LODSB cmp al, 0 JE cl2out cmp al, + jne Cl2O VR; If not space @@: LODSB cmp al, 32;      Capturing Contiguous Spaces JE @B inc ECX; ARG counter + + cmp al, 0 je cl2out cl2ovr:jmp l2st clSubLp2: STOSB; The first character of the parameter is written in @@: LODSB cmp al, je cl2out cmp al, 0 JE cl2out sto SB jmp @B Cl2out:mov al, 0 stosb; ---------------------------------  ; space to change back; ---------------------------------mov esi, itembuffer mov edi, itembuffer @@: LODSB cmp al, 0 JE @F cmp AL, 254 jne Nxt1 mov al, nxt1:stosb jmp @B @@:; -------------------------------------------------  ; Replace "" to 0; -------------------------------------------------mov esi, itembuffer mov edi, itembuffer LODSB cmp al, 255; see 108+ line Jne @F mov al, 0; Replace with 0 STOSB mov eax, 4; return 4 pop edi pop ESI ret @@:; ----------------------------------  ; If the number of parameters is insufficient; Itembuffer first set 0;         ----------------------------------. If ecx < argnum Jmp_in:mov edi, Itembuffer mov al, 0 STOSB    ; mov byte ptr [edi],al mov eax, 2; a return value of 2 indicates that the number of parameters is insufficient or argnum is 0 jmp @F. endif mov eax, 1; cmdline successfully processed @@: Pop edi pop esi retargcl ENDP;      #########################################################################;;       This subroutine receives 2 parameters;;       1. The ordinal of the command line argument you want to get.;       2. The cache address of the result.;;       Example: If there are 4 parameters placed in the CmdLine,;       such as Progname arg1 arg2 arg3 arg4, call the function using the following means;;       Invoke argcl,3,addr buffer;;       The ARG3 will be placed in buffer.;       Note that the referenced ARG supports long filenames.;;       Ensure that the buffer size is sufficient to receive parameters;       CmdLine can only have a maximum of 128 bytes long (now 32kb (non-CMD), the code is dated 1999);       In a function, use;;       LOCAL buffer[128]:byte;;       The return value in the EAX;;       0 = GetCommandLine returns null;       1 = cmdline successfully processed;       2 = attempted processing, but insufficient number of parameters or argnum of 0;       3 = number of quotes does not match (not even);       4 = Empty quotation mark (similar to "");; tab and space are defined characters;; ######################################################################## #end
Vulnerability Analysis

An overflow bug occurs when the valid parameter length is >128, or if the argument after the PE file path is long >192.
When a half-width double quotation mark (such as Arg "" arg) occurs inside a string passed into the parameter, the "empty quotation mark" is triggered without swapping the bug, because the line280~line291 author only determines whether the first character is marked as "empty quotation mark".

The author's brain hole is still not big enough (laughter)

"Lao Liu Talk about algorithm 003" command-line parameter processing and obtaining--ARGCL function implementation analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.